Performance Difference Between C and C++ Style File IO
我一直听说C++文件I/O操作要比C样式I/O慢得多,但是我没有发现任何实际的引用,它们比较慢,所以我决定在我的机器上测试它(Ubuntu 12.04,GCC 4.63,Ext4分区格式)。
首先,我在磁盘上写了一个~900MB的文件。
C++(
1 2 3 4 | ofstream file("test.txt"); for(register int i = 0; i < 100000000; i++) file << i << endl; |
C(
1 2 3 4 5 | FILE *fp = fopen("test.txt","w"); for(register int i = 0; i < 100000000; i++) fprintf(fp,"%d ", i); |
我期待着这样的输出,它表明,写一个文件在C + + C中要慢得多,然后我用C和C++ I/O读取相同的文件,这让我惊叹,从文件读取时几乎没有性能上的差异。
C++(
1 2 3 4 5 | int n; ifstream file("test.txt"); for(register int i = 0; i < 100000000; i++) file >> n; |
C(
1 2 3 4 | FILE *fp = fopen("test.txt","r"); for(register int i = 0; i < 100000000; i++) fscanf(fp,"%d", &n); |
那么,为什么用流执行写操作要花这么长时间呢?或者,为什么使用流的阅读速度比写的快?
结论:根据答案和评论,罪魁祸首是
你用
如果您的意思是:
1 2 | file << i << ' '; |
而且,必须在发布模式下编译代码(即启用优化)。
不,C++的输入/输出并不比C的慢很多——如果有的话,一个现代的实现应该在格式化的输入/输出上稍微快一些,因为它不需要解析一个格式字符串,而格式化是通过编译流操作符的链接在编译时确定的。
以下是基准中需要考虑的几个注意事项:
- 使用完全优化(
-O3 进行编译,以获得公平的比较。 - 一个适当的基准需要估计偏差——在实践中,这意味着你需要重复你的测试并交错它们。目前,您的代码对来自后台进程的干扰不具有鲁棒性。您还应该报告重复运行的摘要统计信息,以捕获歪曲估计的异常值。
- 禁用C流与C流的同步(EDOCX1,4)
- 用
' 代替(冲洗)
'std::endl 。 - 不要使用
register 声明——它只是没有任何区别,现代编译器可能会忽略它。
使用
相反,禁用流缓冲会显著降低性能。在没有设置缓冲区的情况下,至少MSVC 2015实现一次将1个字符复制到
1 2 3 | const size_t bufsize = 256*1024; char buf[bufsize]; mystream.rdbuf()->pubsetbuf(buf, bufsize); |
您可以在这里找到一个完整的示例应用程序。