我正在运行一些基准测试,以找到在 C++ 中将大型数组写入文件的最有效方法(在 ASCII 中超过 1Go)。
所以我将 std::ofstream 与 fprintf 进行了比较(请参阅下面我使用的开关)
case 0: {
std::ofstream out(title, std::ios::out | std::ios::trunc);
if (out) {
ok = true;
for (i=0; i<M; i++) {
for (j=0; j<N; j++) {
out<<A[i][j]<<" ";
}
out<<"\n";
}
out.close();
} else {
std::cout<<"Error with file : "<<title<<"\n";
}
break;
}
case 1: {
FILE *out = fopen(title.c_str(), "w");
if (out!=NULL) {
ok = true;
for (i=0; i<M; i++) {
for (j=0; j<N; j++) {
fprintf(out, "%d ", A[i][j]);
}
fprintf(out, "\n");
}
fclose(out);
} else {
std::cout<<"Error with file : "<<title<<"\n";
}
break;
}
我的一个大问题是,与 std::ofstream 相比,fprintf 似乎慢了 12 倍以上。您知道我的代码中问题的根源是什么吗?或者也许 std::ofstream 与 fprintf 相比非常优化?
(还有另一个问题:你知道另一种更快的写入文件的方法吗)
非常感谢
(详细信息:我正在使用 g++ -Wall -O3 进行编译)
fprintf("%d"
需要对格式字符串进行运行时解析,每个整数一次。 ostream& operator<<(ostream&, int)
由编译器解析,每次编译一次。
好吧,
fprintf()
确实需要在运行时做更多的工作,因为它必须解析和处理格式字符串。但是,考虑到输出文件的大小,我预计这些差异影响不大,并且预计代码受 I/O 限制。
因此,我怀疑您的基准在某种程度上存在缺陷。
fsync()/sync()
会发生什么?ofstream中有一个文件缓冲区,这可以减少访问磁盘的次数。另外,fprintf是一个可变参数的函数,它会调用一些va_#函数,但ofstream不会。我认为你可以使用fwrite()或putc()进行测试。
您是否在所显示的代码上游的某个位置设置了sync_with_stdio?
虽然您报告的内容与经验所见相反,但大多数人认为并相信您所看到的应该是常态。 iostream 是类型安全的,而 printf 系列函数是可变参数函数,必须从格式说明符推断 va_list 的类型。
怎么样:
uint32_t foo;
// <some code setting foo>
std::cout<< std::setfill('0') << std::setw(8) << foo << std<<endl;
编译器无法解析它。