C++;iostreams的标准指令性能较差,还是我只是在处理较差的实现? 每次我提到C++标准库IOFROM的慢速性能时,我都会遇到一种不信任的浪潮。然而,我的探查器结果显示,在iostream库代码(完整的编译器优化)上花费了大量时间,从iostream切换到特定于操作系统的I/oapi和自定义缓冲区管理确实带来了一个数量级的改进 < C++标准库做什么额外的工作,是标准要求的,在实践中有用吗?或者有些编译器提供的iostreams实现与手动缓冲区管理具有竞争力吗 基准
为了让事情进展顺利,我编写了两个简短的程序来练习iostreams内部缓冲:C++;iostreams的标准指令性能较差,还是我只是在处理较差的实现? 每次我提到C++标准库IOFROM的慢速性能时,我都会遇到一种不信任的浪潮。然而,我的探查器结果显示,在iostream库代码(完整的编译器优化)上花费了大量时间,从iostream切换到特定于操作系统的I/oapi和自定义缓冲区管理确实带来了一个数量级的改进 < C++标准库做什么额外的工作,是标准要求的,在实践中有用吗?或者有些编译器提供的iostreams实现与手动缓冲区管理具有竞争力吗 基准,c++,performance,iostream,C++,Performance,Iostream,为了让事情进展顺利,我编写了两个简短的程序来练习iostreams内部缓冲: 将二进制数据放入ostringstream 将二进制数据放入char[]缓冲区 使用back\u插入器将二进制数据放入向量中 新建:向量简单迭代器 NEW:将二进制数据直接放入stringbuf 新建:向量简单迭代器加边界检查 请注意,ostringstream和stringbuf版本运行的迭代次数较少,因为它们的速度要慢得多 在ideone上,ostringstream比std:copy+back\u inser
- 将二进制数据放入
ostringstream
- 将二进制数据放入
缓冲区char[]
- 使用
back\u插入器将二进制数据放入
向量中
- 新建:
简单迭代器向量
- NEW:将二进制数据直接放入
stringbuf
- 新建:
简单迭代器加边界检查向量
ostringstream
和stringbuf
版本运行的迭代次数较少,因为它们的速度要慢得多
在ideone上,ostringstream
比std:copy
+back\u inserter
+std::vector
慢约3倍,比memcpy
慢约15倍进入原始缓冲区。当我将我的实际应用程序切换到自定义缓冲时,这感觉与评测前后一致
这些都是内存缓冲区,所以IO流的慢不能归咎于慢磁盘I/O、过多刷新、与STDIO同步,或者人们用来解释C++标准库IOSWATE的慢速的任何其他事情。 <> P> >在其他系统上查看基准和对常用实现(例如GCC的LBC++、Visual C++、英特尔C++)和标准中的开销有多大的评论是很好的。 这项测试的基本原理 许多人正确地指出iostream更常用于格式化输出。然而,它们也是由C++标准提供的唯一的二进制文件访问的现代API。但是,对内部缓冲进行性能测试的真正原因适用于典型的格式化I/O:如果iostreams不能向磁盘控制器提供原始数据,那么当它们也负责格式化时,它们又如何能够跟上呢
基准时间 所有这些都是外部(k
)循环的每次迭代
在ideone上(gcc-4.3.4,未知操作系统和硬件):
:53毫秒ostringstream
:27毫秒stringbuf
和向量
:17.6毫秒反向插入器
使用普通迭代器:10.6 ms向量
迭代器和边界检查:11.4毫秒vector
:3.7毫秒char[]
:73.4毫秒,71.6毫秒ostringstream
:21.7毫秒,21.3毫秒stringbuf
和向量
:34.6毫秒,34.4毫秒反向插入器
使用普通迭代器:1.10毫秒,1.04毫秒向量
迭代器和边界检查:1.11毫秒、0.87毫秒、1.12毫秒、0.89毫秒、1.02毫秒、1.14毫秒vector
:1.48毫秒,1.57毫秒char[]
Visual C++ 2010 x86,配置文件优化优化>代码> Cl/ox/EHSC/GL/C<<代码>,<代码>链接/LTCG:PGI,运行,<代码>链接/LTCG:PGO < /C> >,测量:
:61.2毫秒,60.5毫秒ostringstream
使用普通迭代器:1.04毫秒,1.03毫秒向量
g++-O3
:
:62.7毫秒,60.5毫秒ostringstream
:44.4毫秒,44.5毫秒stringbuf
和向量
:13.5毫秒,13.6毫秒反向插入器
使用普通迭代器:4.1毫秒,3.9毫秒向量
迭代器和边界检查:4.0毫秒,4.0毫秒vector
:3.57毫秒,3.75毫秒char[]
同一台笔记本电脑,Visual C++ 2008 SP1,<代码> Cl/ox/EHSC >:
:88.7毫秒,87.6毫秒ostringstream
:23.3毫秒,23.4毫秒stringbuf
和向量
:26.1毫秒,24.5毫秒反向插入器
带普通迭代器:3.13毫秒,2.48毫秒vector
迭代器和边界检查:2.97毫秒,2.53毫秒vector
:1.52毫秒,1.25毫秒char[]
同一台笔记本电脑,Visual C++ 2010位64位编译器:
:48.6毫秒,45.0毫秒ostringstream
:16.2毫秒,16.0毫秒stringbuf
和向量
:26.3毫秒,26.5毫秒反向插入器
使用普通迭代器:0.87毫秒,0.89毫秒向量
迭代器和边界检查:0.99毫秒,0.99毫秒vector
:1.25毫秒,1.24毫秒char[]
ostringstream
和vector
重新分配对最终结果的影响应该很小
EDIT:Oops,在向量中发现了一个bug
——使用普通迭代器时,迭代器没有升级,因此缓存命中过多。我在想