每当我提到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++中,使用cin和cout太慢了.使用这些,您将保证无法通过适当的输入或输出解决任何问题.请改用printf和scanf.
有人可以澄清一下吗?真的在C++程序中使用scanf()比使用cin更快吗?如果是,那么在C++程序中使用它是一个好习惯吗?我认为这是C特定的,虽然我只是学习C++ ...
我通常使用cout和cerr写文本到控制台.然而,有时我发现使用旧的printf陈述更容易.我需要格式化输出时使用它.
我将使用它的一个例子是:
// Lets assume that I'm printing coordinates...
printf("(%d,%d)\n", x, y);
// To do the same thing as above using cout....
cout << "(" << x << "," << y << ")" << endl;
Run Code Online (Sandbox Code Playgroud)
我知道我可以使用格式化输出,cout但我已经知道如何使用printf.有什么理由我不应该使用这个printf陈述吗?
我想创建一个包含嵌入信息的字符串.实现我想要的一种方式(不是唯一的方法)称为字符串插值或变量替换,其中字符串中的占位符用实际值替换.
在C中,我会做这样的事情:
printf("error! value was %d but I expected %d",actualValue,expectedValue)
Run Code Online (Sandbox Code Playgroud)
而如果我在python中编程,我会做这样的事情:
"error! value was {0} but I expected {1}".format(actualValue,expectedValue)
Run Code Online (Sandbox Code Playgroud)
这两个都是字符串插值的例子.
我怎么能用C++做到这一点?
重要提示:
std::cout如果我想将这样的消息打印到标准输出(不是字符串插值,但打印出我想要的字符串类型):cout << "error! value was " << actualValue << " but I expected "
<< expectedValue;
Run Code Online (Sandbox Code Playgroud)
我不想将字符串打印到stdout.我想将std::string一个参数作为参数传递给一个函数(例如异常对象的构造函数).
编辑
对于我的直接使用,我并不关心性能(我正在大声提出异常!). 但是,了解各种方法的相对性能通常非常有用.
为什么不直接使用printf(毕竟C++是C的超集......)? 这个答案讨论了一些原因.根据我的理解,类型安全是一个重要原因:如果你把%d放在那里,你放在那里的变量最好真的可以转换为整数,因为这就是函数如何计算它是什么类型.使用一种方法可以更加安全,该方法使用要插入的变量的实际类型的编译时知识.
论坛已经讨论过类似的话题.但是我在下面的代码中有一些不同的问题:
double total;
cin >> total;
cout << fixed << setprecision(2) << total;
Run Code Online (Sandbox Code Playgroud)
如果我提供输入,100.00那么程序打印只是100但不是100.00
我怎么打印100.00?
我看到了这个链接,但我不是要求使用"extern"的代码性能下降.我的意思是没有"extern",在C++中使用C库时是否存在"上下文切换"? 在C++应用程序中使用纯C(非类包装)函数时是否有任何问题?
我刚刚读到了关于FastFormat C++ i/o格式库的文章,看起来好得令人难以理解:甚至比printf更快,类型安全,以及我认为令人满意的界面:
// prints: "This formats the remaining arguments based on their order - in this case we put 1 before zero, followed by 1 again"
fastformat::fmt(std::cout, "This formats the remaining arguments based on their order - in this case we put {1} before {0}, followed by {1} again", "zero", 1);
// prints: "This writes each argument in the order, so first zero followed by 1"
fastformat::write(std::cout, "This writes each argument in the order, so …Run Code Online (Sandbox Code Playgroud) 为了更快地输入,我读到你可以做file-redirection并包含cin已设置输入的文件.
理论上它应该像下面这样使用
App.exe inputfile outputfile
Run Code Online (Sandbox Code Playgroud)
据我在C++ Primer一书中所理解,以下C++代码[1]应该cin从文本文件中读取输入,不需要像[2]这样的任何其他特殊指示
[2]
include <fstream>
ofstream myfile;
myfile.open ();
Run Code Online (Sandbox Code Playgroud)
[1]以下C++代码......
#include <iostream>
int main(){
int val;
std::cin >> val; //this value should be read automatically for inputfile
std::cout << val;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我错过了什么吗?
我已经阅读了三种方法,可以从各种来源以c ++的形式将内容打印到控制台.
using namespace std;然后使用cout(CodeBlocks标准版)std::cout和std::endl;(C++ Primer)printf(HackerRank)哪个是首选,为什么?
c++ ×10
c ×3
performance ×3
iostream ×2
c++11 ×1
c-libraries ×1
fastformat ×1
file ×1
formatting ×1
include ×1
io ×1
precision ×1