每当我提到C++标准库iostream的慢性能时,我都会遇到一阵难以置信的风潮.然而,我有剖析器结果显示在iostream库代码中花费了大量时间(完全编译器优化),并且从iostream切换到特定于操作系统的I/O API和自定义缓冲区管理确实提供了一个数量级的改进.
C++标准库做了多少额外工作,标准是否需要它,它在实践中是否有用?或者有些编译器提供了与手动缓冲区管理竞争的iostream实现吗?
为了解决问题,我编写了几个简短的程序来练习iostreams内部缓冲:
ostringstream http://ideone.com/2PPYwchar[]缓冲区http://ideone.com/Ni5ctvector<char>使用http://ideone.com/Mj2Fi将二进制数据放入其中back_inserter vector<char>简单的迭代器http://ideone.com/9iitvstringbuf http://ideone.com/qc9QAvector<char>简单的迭代器加边界检查http://ideone.com/YyrKy请注意,ostringstream和stringbuf版本运行的迭代次数较少,因为它们的速度要慢得多.
在ideone上,它ostringstream比std:copy+ back_inserter+ 慢大约3倍std::vector,比memcpy原始缓冲区慢大约15倍.当我将实际应用程序切换到自定义缓冲时,这与前后分析一致.
这些都是内存缓冲区,因此iostream的缓慢不能归咎于缓慢的磁盘I/O,过多的刷新,与stdio的同步,或者人们用来解释C++标准库观察到的缓慢的任何其他事情iostream的.
很高兴看到其他系统上的基准测试和常见实现的评论(例如gcc的libc ++,Visual C++,Intel C++)以及标准规定了多少开销.
许多人都正确地指出,iostream更常用于格式化输出.但是,它们也是C++标准提供的二进制文件访问的唯一现代API.但是对内部缓冲进行性能测试的真正原因适用于典型的格式化I/O:如果iostreams无法保持磁盘控制器提供原始数据,那么当他们负责格式化时,他们怎么可能跟上呢?
所有这些都是outer(k)循环的每次迭代.
在ideone上(gcc-4.3.4,未知的操作系统和硬件):
ostringstream:53毫秒stringbuf:27毫秒vector<char>并且back_inserter:17.6毫秒vector<char> 与普通迭代器:10.6毫秒vector<char> 迭代器和边界检查:11.4 mschar[]:3.7毫秒在我的笔记本电脑上(Visual C++ 2010 x86,cl …
我正在使用我的C++项目中的Ubuntu环境中的Eclipse.
我使用该itoa函数(在Visual Studio上完美运行),编译器抱怨itoa未声明.
我包括<stdio.h>,<stdlib.h>,<iostream>这于事无补.