我编写了以下简单的测试代码,该代码在子目录中创建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
秒内创建。 (使用我的PC)
问题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
秒似乎是正常的并且已经优化了?
感谢您分享见解!
答案 0 :(得分:4)
文件的创建速度取决于硬件,更快的驱动器可以更快地创建文件。
我在ARM处理器上运行您的代码(在使用termux的手机上使用Snapdragon 636)证明了这一点,现在手机的闪存非常快到I / O。因此,大多数情况下,运行时间少于3秒,而5秒则是。由于驱动器必须处理多进程读写,因此预计会出现这种变化。 您报告说硬件花费了47秒。 因此,您可以放心地得出结论,I / O速度很大程度上取决于硬件。
我一直想对您的代码做一些优化,所以我使用了两种不同的方法。
为I / O使用C副本
使用C ++,但一次性编写大块代码。
我在手机上运行了模拟。我运行了50次,结果如下。
C使用fprintf最快可以平均花费2.73928秒将单词写在10000个文本文件上
一次完成整行的C ++编写花费了2.7899秒。我使用sprintf将完整的行放入char []中,然后在流上使用<<操作符编写。
C ++普通(您的代码)花费了2.8752秒
这种现象是可以预期的,分块写入速度更快。阅读this答案以了解原因。毫无疑问,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作为编译器。
如果您有其他方法,请告诉我,我也会进行测试。如果您发现错误,请告诉我,我会尽快纠正。