Voici ce que j'ai recueillies jusqu'à présent:
Mise en mémoire tampon:
Si par défaut la mémoire tampon est très faible, l'augmentation de la taille de la mémoire tampon peut certainement améliorer les performances:
- il réduit le nombre de HDD hits
- il réduit le nombre d'appels système
Tampon peut être définie par l'accès au sous-jacents streambuf
mise en œuvre.
char Buffer[N];
std::ifstream file("file.txt");
file.rdbuf()->pubsetbuf(Buffer, N);
// the pointer reader by rdbuf is guaranteed
// to be non-null after successful constructor
Paramètres Régionaux De La Manipulation:
Paramètres régionaux pouvez effectuer la conversion de caractères, de filtrage, et plus de trucs astucieux où des nombres ou des dates sont impliqués. Ils passent par un système complexe de répartition dynamique et les appels virtuels, de sorte que leur suppression peut aider à coupe vers le bas la peine de frapper.
La valeur par défaut C
locale n'est pas destiné à effectuer la conversion ainsi que d'être uniforme sur l'ensemble des machines. C'est une bonne valeur par défaut à utiliser.
Synchronisation:
Je ne pouvais pas voir tout l'amélioration de la performance à l'aide de cette installation.
On peut accéder à un mondial de réglage (membre statique d' std::ios_base
) à l'aide de l' sync_with_stdio
fonction statique.
Mesures:
Jouer avec cela, j'ai joué avec un programme simple, compilé à l'aide de gcc 3.4.2
sur SUSE 10p3 avec -O2
.
C : 7.76532 e+06
C++: 1.0874 e+07
Ce qui représente un ralentissement d'environ 20%
... pour le code par défaut. En effet, la falsification de la mémoire tampon (en C ou C++) ou les paramètres de synchronisation (C++) n'a pas produit d'amélioration.
Résultats par d'autres:
@Irfy sur g++ 4.7.2-2ubuntu1, -O3, virtualisé Ubuntu 11.10, 3.5.0-25-generic, x86_64, assez de ram/cpu, 196MB de plusieurs "trouver / >> largefile.txt" s'exécute
C : 634572
C++: 473222
C++ 25% plus rapide
@Matteo Italia sur g++ 4.4.5, -O3, Linux Ubuntu 10.10 x86_64 avec un nombre aléatoire de 180 MO fichier
C : 910390
C++: 776016
C++ 17% plus rapide
@Bogatyr sur g++ i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. construire 5664), mac mini, 4 go de ram, de repos, sauf pour ce test avec une 168MB datafile
C : 4.34151 e+06
C++: 9.14476 e+06
C++ 111% plus lent
Donc la réponse est: c'est une qualité de la mise en œuvre question, et dépend vraiment de la plate-forme :/
Le code dans son intégralité ici pour ceux qui s'intéressent à l'analyse comparative:
#include <fstream>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <cstdio>
#include <sys/time.h>
template <typename Func>
double benchmark(Func f, size_t iterations)
{
f();
timeval a, b;
gettimeofday(&a, 0);
for (; iterations --> 0;)
{
f();
}
gettimeofday(&b, 0);
return (b.tv_sec * (unsigned int)1e6 + b.tv_usec) -
(a.tv_sec * (unsigned int)1e6 + a.tv_usec);
}
struct CRead
{
CRead(char const* filename): _filename(filename) {}
void operator()() {
FILE* file = fopen(_filename, "r");
int count = 0;
while ( fscanf(file,"%s", _buffer) == 1 ) { ++count; }
fclose(file);
}
char const* _filename;
char _buffer[1024];
};
struct CppRead
{
CppRead(char const* filename): _filename(filename), _buffer() {}
enum { BufferSize = 16184 };
void operator()() {
std::ifstream file(_filename, std::ifstream::in);
// comment to remove extended buffer
file.rdbuf()->pubsetbuf(_buffer, BufferSize);
int count = 0;
std::string s;
while ( file >> s ) { ++count; }
}
char const* _filename;
char _buffer[BufferSize];
};
int main(int argc, char* argv[])
{
size_t iterations = 1;
if (argc > 1) { iterations = atoi(argv[1]); }
char const* oldLocale = setlocale(LC_ALL,"C");
if (strcmp(oldLocale, "C") != 0) {
std::cout << "Replaced old locale '" << oldLocale << "' by 'C'\n";
}
char const* filename = "largefile.txt";
CRead cread(filename);
CppRead cppread(filename);
// comment to use the default setting
bool oldSyncSetting = std::ios_base::sync_with_stdio(false);
double ctime = benchmark(cread, iterations);
double cpptime = benchmark(cppread, iterations);
// comment if oldSyncSetting's declaration is commented
std::ios_base::sync_with_stdio(oldSyncSetting);
std::cout << "C : " << ctime << "\n"
"C++: " << cpptime << "\n";
return 0;
}