测试目的:在LINUX下以OI/ACM竞赛为目的测试C++的两种输入输出的速度区别。

测试数据:test.in文件随机生成的5000000个不超过5000000的非负整数,一行,以单个空格隔开,末尾有一个回车符(行末行首无多余空格),一一读入并输出至test.out文件。

测试代码:
1. test_cstream.cpp 使用iostream和cstdio库,freopen重定向标准输入输出,使用流cin/cout。
2. test_fstream.cpp 使用iostream和fstream库,建立 类ifstream和ofstream的 对象fin和fout,使用构造函数指向文件,使用流fin/fout。
3. test_cstdio1.cpp 使用cstdio库,freopen重定向标准输入输出,使用函数scanf/printf。
4. test_cstdio2.cpp 使用cstdio库,定义两个FILE指针fin/fout,使用函数fscanf/fprintf。
5. test_pascal.pas PASCAL程序,用以比对;使用assign(‘ ‘, input/output),使用过程read/write。

测试方式:把CPU功率调制最低以凸显差距,使用LINUX自带的time来计时,每次运行后删除输出文件test.out。为了测试方便,编写了一个bash脚本。多次运行后确认结果相差不大。

测试结果:
C++ I/O Speed Test (int) Under Linux
Linux MAGI-laptop 2.6.31-19-generic #56-Ubuntu SMP Thu Jan 28 01:26:53 UTC 2010 i686 GNU/Linux

Method Time
iostream (cin/cout + freopen) real 0m39.034s
user 0m11.677s
sys 0m27.054s
iostream + fstream real 0m2.826s
user 0m2.628s
sys 0m0.192s
cstdio (scanf/printf + freopen) real 0m2.335s
user 0m2.172s
sys 0m0.160s
cstdio (fscanf/fprintf + fopen) real 0m2.398s
user 0m2.268s
sys 0m0.128s
Pascal real 0m3.257s
user 0m2.404s
sys 0m0.844s

测试结论:
显而易见的,使用freopen重定向的标准输入输出流极慢无比。同样使用流式的fstream却要优秀不少,甚至只是稍逊于scanf和printf。传说中较快的scanf和printf也仅仅是以微弱优势领先,当然,如果数据规模扩大将更加明显,只不过这么大的数据也不大可能。(fscanf/fprintf与scanf/printf相差无几,只是稍慢一点点。)另外,奇怪的是PASCAL竟然比C++慢!!莫非C++的 I/O魔咒已经不复存在了?PASCAL仅存的优势也消失了?

提供测试包:http://down.robotshell.org/studio/Cpp_IO_TEST.zip

解压后文件夹内有所有源代码(包括5个测试程序和bash脚本)。另外,由于输入文件巨大(40M左右),所以只提供了一个随机数据生成器gen.pas。

请LINUX用户直接运行run.sh即可,自动编译所有源代码,生成输入文件并打印测试结果。(请先确定已安装g++以及fpc)

感谢xkszltl的帮助,在Windows下测试了,果真同刘汝佳所说的一样,两个平台是天壤之别:

测试方式:CPU(Intel P8800)高功率,硬盘Seagate 500GB 7200转,内存金士顿4GB DDRII 800,操作系统Win7,评测软件清澄。
测试结果:(由清澄测试)

iostream (cin/cout + freopen): 34.01s
iostream + fstream: 3.48s
cstdio (scanf/printf + freopen): 3.42s
cstdio (fscanf/fprintf + fopen): 3.48s
Pascal: 2.46s