,最近在知乎上看了篇帖子,题目是为什么C++没有C语言快,如下图:
,,恰好之前研究过这块,所以借助本文,分析下这个问题(无意于语言之争,单纯是从技术角度)。
,众所周知,C++兼容了C的所有功能,显然从所有角度去对比分析是不现实的,所以本文从我们常用的输入输出即标准流(iostream和stdio)的角度来分析讲解。
,为了更加直观地来对比分析,写了个示例,通过scanf和cin读文件,然后分析两种方式的性能高低,代码如下:,编译,运行之后,输出如下:,从上述输出来看,cin的耗时是scanf的3倍多,果真如此么?
,C++性能真的差C这么多吗?直接颠覆了对C++的认知,即使性能真的低,也得知道为什么低吧,于是开始研究,发现C++为了兼容C,在C标准流(stdio)和C++标准流(iostrem)保持同步,这样就可以混合使用C和C++风格的I/O,且能保证得到合理和预期的结果,而正是这个同步导致C++在cin性能上有损失。如果禁用同步,则允许C++流拥有自己的独立缓冲区,这样性能就会提升很多。
,那么是否可以禁用该同步功能呢?
,C++提供了一个函数std::ios::sync_with_stdio,声明如下:
,如果参数为false,则代表禁用此同步。从上面声明可以看出,默认情况下 __sync = true也就是说禁用同步,而如果__sync为false的话,则会有如下操作:,从上述代码,进一步验证了我们上面的说法,如果禁用了同步功能,则C++流使用自己的缓冲区buf_cin(此处以cin为例),几种buffer的定义如下:,好了,截止到现在,我们已经搞清楚了为什么C++流性能要慢于C,为了验证是否真的是因为使用了同步功能而导致的性能差异,使用std::ios::sync_with_stdio(false)关闭同步,代码示例如下:,编译,运行后,输出如下:,可以看出禁用同步后,二者的性能基本一致。
,既然禁用同步后,C++流的性能与C基本一致,那么是否直接禁用呢?答案是依赖于具体的使用场景。
,1、同步的C++流是线程安全的,也就说来自不同线程的输出可能会交错,但数据不会产生竞争,而如果禁用同步,则可能出现意想不到的结果。
,2、如果禁用了同步功能,输入输出顺序可能会得不到我们想要的结果。,上述代码执行后,输出a b c ,符合我们的预期。
,如果加上禁用同步代码,如下:,编译、运行之后,结果为a c b,与我们期望的不一致。
,如果使用C编程,那么使用C stdio,而如果使用C++编程,则建议使用C++ I/O。如果在某些特殊场景下,需要混合使用,那么强烈建议不要禁用同步,否则会得到意想不到的结果。
© 版权声明
文章版权归作者所有,未经允许请勿转载。