[英]Optimizing .txt files creation speed
我編寫了以下簡單的測試代碼,該代碼在子目錄中創建10000個空的.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;
}
一切正常。 所有10000個.txt文件都在~3.55
秒內創建。 (使用我的電腦)
問題1:忽略從int
到std::string
等的轉換,對於程序可以更快地創建文件,我有什么可以優化的地方嗎? 我特別是指std::ofstream outfile
用法-也許使用其他方法會更快一些?
無論如何,與以下相比, ~3,55
秒令人滿意:
我已經修改了該函數,所以現在它還會用一些隨機的i
整數數據和一些常量文本填充.txt文件:
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
秒似乎正常且已優化?
感謝您分享您的見解!
文件的創建速度取決於硬件,更快的驅動器可以更快地創建文件。
從我在ARM處理器 (Snapdragon 636,在使用termux的手機上)上運行您的代碼這一事實就可以明顯看出這一點,現在手機的閃存在I / O方面非常快。 因此,大多數情況下,運行時間不到3秒,而有些時候則是5秒 。 由於驅動器必須處理多進程讀寫,因此預計會出現這種變化。 您報告說,硬件花費了47秒。 因此,您可以放心得出結論,I / O速度很大程度上取決於硬件。
盡管如此,我還是想對您的代碼做一些優化,並且我使用了兩種不同的方法。
使用C副本進行I / O
使用C ++,但一次性編寫大塊代碼。
我在手機上運行了模擬。 我運行了50次,結果如下。
使用fprintf,C最快平均花費2.73928秒在10000個文本文件上寫單詞
一次完成整行的C ++編寫花費了2.7899秒。 我使用sprintf將完整的行放入char []中,然后在流上使用<<操作符進行編寫。
C ++普通(您的代碼)花了2.8752秒
此行為是預期的,分塊寫入速度更快。 閱讀有關原因的答案。 毫無疑問,C是最快的。
您可能會在這里注意到,差異並不明顯,但是如果您使用的是I / O速度較慢的硬件,那么這會變得很重要。
這是我用於仿真的代碼。 您可以自己對其進行測試,但請確保使用您自己的命令替換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作為編譯器。
如果您還有其他方法要告訴我,我也會進行測試。 如果您發現錯誤,請告訴我,我們將盡快予以糾正。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.