В чем секрет скорости работы функции filesystem :: copy? - PullRequest
0 голосов
/ 10 июля 2020

Я пытаюсь достичь скорости filesystem::copy при чтении содержимого файла и записи этого содержимого в новый файл «операция копирования», но я не могу достичь этой скорости.

Следующее это простой пример моей попытки:

void Copy(const wstring &fromPath, const wstring &toPath) {
    ifstream readFile(fromPath.c_str(), ios_base::binary|ios_base::ate);    
    char* fileContent = NULL;
    if (!readFile) { cout << "Cannot open the file.\n"; return; }
    ofstream writeFile(toPath.c_str(), ios_base::binary);
    streampos size = readFile.tellg();
    readFile.seekg(0, ios_base::beg);
    fileContent = new char[size];
    readFile.read(fileContent, size);
    writeFile.write(fileContent, size);
    readFile.close();
    writeFile.close();
    delete[] fileContent;
}

Предыдущий код может копировать файл .iso его размер «1,48 ГБ» между «8–9» секундами, а filesystem::copy может копировать тот же файл в промежутке от "1 до 2" секунд максимум. Примечание : я не хочу использовать C ++ 17 в текущий период.

Как мне сделать, чтобы скорость моей функции была как filesystem::copy?

1 Ответ

4 голосов
/ 10 июля 2020

Ваша реализация должна выделить буфер размером с весь файл. Это расточительно, вы можете просто прочитать 64 КБ, написать 64 КБ и повторить для следующих блоков. Если вы прочитаете все это целиком, а затем напишете все это, вы в конечном итоге будете дважды загружать и выгружать весь файл.

Возможно, несколько потоков могут читать / писать отдельно (при условии, что чтение остается впереди). Это может ускорить процесс.

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

Существует множество других приемов, которые может использовать реализация filesystem::copy. Вы могли go увидеть, как он закодирован, существует множество открытых реализаций.

Однако есть предостережение: реализация стандартной библиотеки может полагаться на специфические c поведения, которые язык не гарантирует. Таким образом, вы не можете просто скопировать код в другой компилятор / архитектуру / платформу.

...