Оптимизация скорости создания .txt файлов - PullRequest
0 голосов
/ 27 декабря 2018

Я написал следующий простой тестовый код, который создает 10 000 пустых .txt файлов в подкаталоге.

#include <iostream>
#include <time.h>
#include <string>
#include <fstream>

void CreateFiles()
{
    int i = 1;
    while (i <= 10000) {
        int filename = i;
        std::string string_i = std::to_string(i);
        std::string file_dir = ".\\results\\"+string_i+".txt";
        std::ofstream outfile(file_dir);
        i++;
    }
}

int main()
{
    clock_t tStart1 = clock();
    CreateFiles();
    printf("\nHow long it took to make files: %.2fs\n", (double)(clock() - tStart1)/CLOCKS_PER_SEC);
    std::cin.get();
    return 0;
}

Все отлично работает.Все 10 000 .txt файлов создаются в течение ~3.55 секунд.(используя мой компьютер)

Вопрос 1: Игнорирование преобразования из int в std::string и т. д., есть ли что-нибудь, что я мог бы оптимизировать здесь для программы, чтобы быстрее создавать файлы?Я специально имею в виду использование std::ofstream outfile - возможно, использование чего-то другого было бы значительно быстрее?

В любом случае, ~3,55 секунд удовлетворительно по сравнению со следующим:

Я так правильно изменил функциютеперь он также заполнил бы файлы .txt некоторыми случайными i целочисленными данными и некоторым постоянным текстом:

void CreateFiles()
{
    int i = 1;
    while (i <= 10000) {
        int filename = i;
        std::string string_i = std::to_string(i);
        std::string file_dir = ".\\results\\"+string_i+".txt";
        std::ofstream outfile(file_dir);

        // Here is the part where I am filling the .txt with some data
        outfile << i << " some " << i << " constant " << i << " text " << i << " . . . " 
        << i << " --more text-- " << i << " --even more-- " << i;
        i++;
    }
}

И теперь все (создание файлов .txt и заполнение его короткими данными) выполняется внутри... ~37 секунд.Это огромная разница.И это только 10 000 файлов.

Вопрос 2: Могу ли я что-нибудь оптимизировать здесь?Возможно, существует какая-то альтернатива, которая бы быстрее заполняла файлы .txt.Или, может быть, я забыл о чем-то очень очевидном, что замедляет весь процесс?

Или, может быть, я немного преувеличиваю, и ~37 секунд кажется нормальным и оптимизированным?

Спасибо, что поделилисьваше понимание!

1 Ответ

0 голосов
/ 27 декабря 2018

Скорость создания файла зависит от оборудования, чем быстрее диск, тем быстрее вы можете создавать файлы.

Это видно из того факта, что Я запустил ваш код на процессоре ARM (Snapdragon 636, на мобильном телефоне, использующем termux), теперь мобильные телефоны имеют флэш-память, которая очень быстрая, когда дело доходит до ввода / вывода.Так что он работал меньше 3 секунд большую часть времени и некоторое время 5 секунд .Это изменение ожидается, поскольку накопитель должен обрабатывать многопроцессные операции чтения. Вы сообщили, что для вашего оборудования это заняло 47 секунд. Таким образом, вы можете смело утверждать, что скорость ввода-вывода существенно зависит от аппаратного обеспечения.


НетМеньше я думал оптимизировать ваш код и использовал 2 разных подхода.

  • Использование аналога C для ввода-вывода

  • Использование C ++, но запись в блоке за один раз.

Я запустил симуляцию на своем телефоне.Я запустил его 50 раз, и вот результаты.

  • C быстрее всего набрал 2,73928 секунды, чтобы написать ваше слово в 10000 текстовых файлах, используя fprintf

  • Написание C ++ с полной строкой за один раз заняло 2.7899 секунд.Я использовал sprintf, чтобы получить полную строку в char [], затем написал, используя оператор << onstream. </p>

  • C ++ Normal (Ваш код) занял 2,8752 секунды

Такое поведение ожидается, запись кусками быстрее.Прочитайте этот ответ на вопрос, почему.C был самым быстрым, без сомнения.

Здесь вы можете заметить, что разница не столь значительна, но если вы работаете на оборудовании с медленным вводом-выводом, это становится значительным.


Вот код, который я использовал длямоделирование.Вы можете проверить это самостоятельно, но обязательно замените аргумент std::system вашими собственными командами (отличающимися для windows).

#include <iostream>
#include <time.h>
#include <string>
#include <fstream>
#include <stdio.h>

void CreateFiles()
{
    int i = 1;
    while (i <= 10000) {
       // int filename = i;
        std::string string_i = std::to_string(i);
        std::string file_dir = "./results/"+string_i+".txt";
        std::ofstream outfile(file_dir);

        // Here is the part where I am filling the .txt with some data
        outfile << i << " some " << i << " constant " << i << " text " << i << " . . . " 
        << i << " --more text-- " << i << " --even more-- " << i;
        i++;
    }
}

void CreateFilesOneGo(){
    int i = 1;
    while(i<=10000){
        std::string string_i = std::to_string(i);
        std::string file_dir = "./results3/" + string_i + ".txt";
        char buffer[256];
        sprintf(buffer,"%d some %d constant %d text %d . . . %d --more text-- %d --even more-- %d",i,i,i,i,i,i,i);
        std::ofstream outfile(file_dir);
        outfile << buffer;
        i++;
    }
}

void CreateFilesFast(){
    int i = 1;
    while(i<=10000){
    // int filename = i;
    std::string string_i = std::to_string(i);
    std::string file_dir = "./results2/"+string_i+".txt";
    FILE *f = fopen(file_dir.c_str(), "w");
    fprintf(f,"%d some %d constant %d text %d . . . %d --more text-- %d --even more-- %d",i,i,i,i,i,i,i);
    fclose(f);
    i++;
    }
}

int main()
{
    double normal = 0, one_go = 0, c = 0;
    for (int u=0;u<50;u++){
        std::system("mkdir results results2 results3");

        clock_t tStart1 = clock();
        CreateFiles();
        //printf("\nNormal : How long it took to make files: %.2fs\n", (double)(clock() - tStart1)/CLOCKS_PER_SEC);
        normal+=(double)(clock() - tStart1)/CLOCKS_PER_SEC;

        tStart1 = clock();
        CreateFilesFast();
        //printf("\nIn C : How long it took to make files: %.2fs\n", (double)(clock() - tStart1)/CLOCKS_PER_SEC);
        c+=(double)(clock() - tStart1)/CLOCKS_PER_SEC;

        tStart1 = clock();
        CreateFilesOneGo();
        //printf("\nOne Go : How long it took to make files: %.2fs\n", (double)(clock() - tStart1)/CLOCKS_PER_SEC);
        one_go+=(double)(clock() - tStart1)/CLOCKS_PER_SEC;

        std::system("rm -rf results results2 results3");
        std::cout<<"Completed "<<u+1<<"\n";
    }

    std::cout<<"C on average took : "<<c/50<<"\n";
    std::cout<<"Normal on average took : "<<normal/50<<"\n";
    std::cout<<"One Go C++ took : "<<one_go/50<<"\n";

    return 0;
}

Также я использовал clang-7.0 в качестве компилятора.

Еслиу вас есть другой подход, дайте мне знать, я тоже буду проверять.Если вы обнаружите ошибку, сообщите мне, я исправлю ее как можно скорее.

...