我一直听说C++文件I/O操作比C风格的I/O操作慢得多得多。但是我没有找到任何关于它们实际有多慢的实用参考资料,所以我决定在我的机器上进行测试(Ubuntu 12.04,GCC 4.6.3,ext4分区格式)。
首先我在硬盘上写了一个大约900MB的文件。
C++ (ofstream
):163秒
ofstream file("test.txt");
for(register int i = 0; i < 100000000; i++)
file << i << endl;
C (fprintf
函数): 12秒
FILE *fp = fopen("test.txt", "w");
for(register int i = 0; i < 100000000; i++)
fprintf(fp, "%d\n", i);
我本来就期望出现这样的输出结果,它表明在C++中写文件要比C慢得多。然后我使用C和C++ I/O读取同一个文件。让我惊喜的是,在从文件中读取时几乎没有性能差异。
C++ (ifstream
): 12秒
int n;
ifstream file("test.txt");
for(register int i = 0; i < 100000000; i++)
file >> n;
C (fscanf
): 12个字符
FILE *fp = fopen("test.txt", "r");
for(register int i = 0; i < 100000000; i++)
fscanf(fp, "%d", &n);
那么,为什么使用流进行写操作需要这么长时间?或者为什么使用流进行读操作比写操作快得多?
结论:罪魁祸首是std::endl
,正如答案和评论所指出的那样。将行
file << i << endl;
改为
file << i << '\n';
将运行时间从163秒减少到16秒。
fstream
比cstdio
慢,但这些差异似乎比我预期的要大一些。你运行时没有低(或无)优化级别吧?由于流主要是通过模板实现的,因此它会被编译到您的代码中,而cstdio
类型函数则编译为库并具有更高级别的优化。 - Mats Peterssonstd::endl
比你在 fprintf 中输出的\n
更多,它会导致流刷新。所以尝试使用file << i << '\n'
。 - Arne Mertz