J'ai besoin de lire 50 millions de données doubles à partir d'un fichier txt et de les stocker dans un vecteur. Au début, j'ai pensé que le fichier io était peut-être trop lent, j'ai donc utilisé le mappage de la mémoire du fichier pour lire le contenu du fichier en mémoire sous forme de blocs. dans le vecteur une par une, mais la lecture des données directement à partir du fichier une par une ne prend que 3 minutes. Après l'avoir optimisé, cela est passé à 5 minutes.
Mon plan d'optimisation consiste à lire l'intégralité du fichier en mémoire, à le placer dans un tampon char*, puis à utiliser vec_name.reserve(50000000); pour allouer 50 millions de capacité afin d'éviter des allocations de mémoire répétées, mais cela semble n'avoir aucun effet.
Est-ce parce que le temps est principalement consacré au push_back ?
Existe-t-il une bonne méthode d'optimisation ? Merci à tous!
Le code clé optimisé est le suivant : (il faut cinq minutes pour lire toutes les données dans le vecteur)
ifstream iVecSim("input.txt");
iVecSim.seekg(0, iVecSim.end);
long long file_size = iVecSim.tellg();//文件大小
iVecSim.seekg(0, iVecSim.beg);
char *buffer = new char[file_size];
iVecSim.read(buffer, file_size);
string input(buffer);
delete[]buffer;
istringstream ss_sim(input);//string流
string fVecSim;
vec_similarity.reserve(50000000);
while (ss_sim.good()) {//从string流中读入vector
ss_sim >> fVecSim;
vec_similarity.push_back(atof(fVecSim.c_str()));
}
Cela n'a aucun sens d'exécuter en mode débogage. Lorsque j'utilise votre code pour l'exécuter en mode release, cela ne prend que 14 secondes environ.
Pour résoudre un problème, trouvez d'abord le problème. J'ai modifié le code comme ceci et découvrez d'abord où est passé le temps
Le goulot d'étranglement réside donc dans la phrase "ss_sim >> fVecSim". atof est assez rapide.
Ma conclusion est donc la suivante : la solution d'optimisation ultime consiste à commencer par le format de stockage et à stocker vos données sous forme binaire au lieu de chaîne. Cela évite la surcharge des fonctions d'E/S de chaîne et de conversion et permet réellement de récupérer les données en quelques secondes.
Le moyen le plus efficace à l'heure actuelle est d'utiliser des flux, et cela peut être vu à partir de l'implémentation de votre code : vous lisez tout le contenu du fichier dans le tampon en même temps, ce qui n'est pas le meilleur moyen. Il est recommandé de lire le buffer[1024] en moyenne à chaque fois, ce qui correspond à 1K, ou à d'autres valeurs. Après la lecture, le pointeur passe à la ligne suivante et continue la lecture jusqu'à la fin de la position EOF
1. S'il n'y a pas de dépendance entre les données, vous pouvez essayer une lecture multithread en blocs ;
2 De plus, la mémoire du vecteur est continue si le parcours ultérieur n'est pas un accès aléatoire, l'utilisation de la liste sera plus efficace. Assez grand nombre.
Vous pouvez passer au style C
scanf
essayezWow, pourquoi traitez-vous ma réponse comme ça ? L'internaute qui m'a dénoncé aimerait demander pourquoi y a-t-il quelque chose qui ne va pas dans cette réponse ?