objective-c - Comment accélérer la lecture de cinquante millions de données d'un fichier et leur stockage dans un vecteur en utilisant C++?
PHP中文网
PHP中文网 2017-05-31 10:36:40
0
4
1055

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()));
        }
PHP中文网
PHP中文网

认证0级讲师

répondre à tous(4)
漂亮男人

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

std::cout << "Start" << std::endl;
    auto n1 = ::GetTickCount();
    auto n2 = 0;
    auto n3 = 0;
    auto n4 = 0;

    while (ss_sim.good())
    {
        auto n = ::GetTickCount();
        ss_sim >> fVecSim;
        n2 += (::GetTickCount() - n);

        n = ::GetTickCount();
        auto v = atof(fVecSim.c_str());
        n3 += (::GetTickCount() - n);

        n = ::GetTickCount();
        vec_similarity.push_back(v);
        n4 += (::GetTickCount() - n);
    }
    n1 = ::GetTickCount() - n1;

    std::cout << "ss_sim >> fVecSim:" << n2 << "ms" << std::endl;
    std::cout << "atof:" << n3 << "ms" << std::endl;
    std::cout << "push_back:" << n4 << "ms" << std::endl;
    std::cout << "Total:" << n1 << "ms" << std::endl;

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.

phpcn_u1582

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

Peter_Zhu

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.

Peter_Zhu

Vous pouvez passer au style C scanf essayez


Wow, 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 ?

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal