0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C++禁用同步的方式

C语言与CPP编程 来源:C语言与CPP编程 作者:C语言与CPP编程 2022-10-17 09:05 次阅读

恰好之前研究过这块,所以借助本文,分析下这个问题(无意于语言之争,单纯是从技术角度)。

众所周知,C++兼容了C的所有功能,显然从所有角度去对比分析是不现实的,所以本文从我们常用的输入输出即标准流(iostream和stdio)的角度来分析讲解。

示例

为了更加直观地来对比分析,写了个示例,通过scanf和cin读文件,然后分析两种方式的性能高低,代码如下:

#include
#include
#include
#include
constintnum=1000000;

voidtime_report(conststd::function&f1,conststd::function&f2){
autostart=std::now();
f1();
autoend=std::now();
std::cout<< "cin cost " << std::duration_cast(end-start).count()<< "ms" << std::endl;

   start = std::now();
   f2();
   end = std::now();
   std::cout << "scanf cost " << std::duration_cast(end-start).count()<< "ms" << std::endl;
}


void write() {
  std::ofstream file("./data");
  for(int i = 0; i < num; ++i) {
    file << rand() <<' ';
    if((i + 1) % 20 == 0) {
      file << std::endl;
    }
  }
}
int main() {
  write(); 
  
  time_report([](){
  freopen("./data","r",stdin);
  int n = 0;
  for(int i=0; i>n;
}
},[](){
freopen("./data","r",stdin);
intn=0;
for(inti=0;i< num; ++i) {
     scanf("%d", &n);
  }
});

return 0;
}

编译,运行之后,输出如下:

cincost686ms
scanfcost189ms

从上述输出来看,cin的耗时是scanf的3倍多,果真如此么?

sync_with_stdio

C++性能真的差C这么多吗?直接颠覆了对C++的认知,即使性能真的低,也得知道为什么低吧,于是开始研究,发现C++为了兼容C,在C标准流(stdio)和C++标准流(iostrem)保持同步,这样就可以混合使用C和C++风格的I/O,且能保证得到合理和预期的结果,而正是这个同步导致C++在cin性能上有损失。如果禁用同步,则允许C++流拥有自己的独立缓冲区,这样性能就会提升很多。

那么是否可以禁用该同步功能呢?

C++提供了一个函数std::sync_with_stdio,声明如下:

staticboolsync_with_stdio(bool__sync=true);

如果参数为false,则代表禁用此同步。从上面声明可以看出,默认情况下__sync = true也就是说禁用同步,而如果__sync为false的话,则会有如下操作:

bool
ios_base::sync_with_stdio(bool__sync){
bool__ret=ios_base::_S_synced_with_stdio;

if(!__sync&&__ret){
//...
cout.rdbuf(&buf_cout);
cin.rdbuf(&buf_cin);
cerr.rdbuf(&buf_cerr);
clog.rdbuf(&buf_cerr);
//...
}
return__ret;
}

从上述代码,进一步验证了我们上面的说法,如果禁用了同步功能,则C++流使用自己的缓冲区buf_cin(此处以cin为例),几种buffer的定义如下:

typedefcharfake_filebuf[sizeof(stdio_filebuf)]
__attribute__((aligned(__alignof__(stdio_filebuf))));
fake_filebufbuf_cout;
fake_filebufbuf_cin;
fake_filebufbuf_cerr;

好了,截止到现在,我们已经搞清楚了为什么C++流性能要慢于C,为了验证是否真的是因为使用了同步功能而导致的性能差异,使用std::sync_with_stdio(false)关闭同步,代码示例如下:


#include

#include #include #include constintnum=1000000; voidtime_report(conststd::function&f1,conststd::function&f2){ autostart=std::now(); f1(); autoend=std::now(); std::cout<< "cin cost " << std::duration_cast(end-start).count()<< "ms" << std::endl;    start = std::now();    f2();    end = std::now();    std::cout << "scanf cost " << std::duration_cast(end-start).count()<< "ms" << std::endl; } void write() {   std::ofstream file("./data");   for(int i = 0; i < num; ++i) {     file << rand() <<' ';     if((i + 1) % 20 == 0) {       file << std::endl;     }   } } int main() {   std::sync_with_stdio(false);   write();       time_report([](){   freopen("./data","r",stdin);   int n = 0;   for(int i=0; i>n; } },[](){ freopen("./data","r",stdin); intn=0; for(inti=0;i< num; ++i) {      scanf("%d", &n);   } }); return 0; }

编译,运行后,输出如下:

cincost178ms
scanfcost189ms

可以看出禁用同步后,二者的性能基本一致。

既然禁用同步后,C++流的性能与C基本一致,那么是否直接禁用呢?答案是依赖于具体的使用场景。

1、同步的C++流是线程安全的,也就说来自不同线程的输出可能会交错,但数据不会产生竞争,而如果禁用同步,则可能出现意想不到的结果。

2、如果禁用了同步功能,输入输出顺序可能会得不到我们想要的结果。

#include
#include

intmain(){
std::cout<< "a ";
  printf("b ");
  std::cout << "c ";
  return 0;
}

上述代码执行后,输出a b c ,符合我们的预期。

如果加上禁用同步代码,如下:

#include
#include

intmain(){
std::sync_with_stdio(false);
std::cout<< "a ";
printf("b ");
std::cout << "c ";

return 0;
}

编译、运行之后,结果为a c b,与我们期望的不一致。

结语

如果使用C编程,那么使用C stdio,而如果使用C++编程,则建议使用C++ I/O。如果在某些特殊场景下,需要混合使用,那么强烈建议不要禁用同步,否则会得到意想不到的结果。

好了,今天的文章就到这,我们下期见!

审核编辑:彭静
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 编程
    +关注

    关注

    88

    文章

    3441

    浏览量

    92443
  • C++
    C++
    +关注

    关注

    21

    文章

    2066

    浏览量

    72903
  • 代码
    +关注

    关注

    30

    文章

    4557

    浏览量

    66835

原文标题:C++性能真的不如C吗?

文章出处:【微信号:C语言与CPP编程,微信公众号:C语言与CPP编程】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    为什么 C 语言没有被 C++ 取代?

    C++
    电路设计
    发布于 :2022年12月28日 19:17:25

    C语言C++常见学习问题

    C++
    电路设计
    发布于 :2023年01月10日 14:07:23

    介绍MATLAB与C++的几种接口方式

    matlab调用c++,应该用mex把cpp编译成 .mex文件供MATLAB在命令行方式下调用吧看下面这片文章文章: 摘自北京理工大学BBSMATLAB是什么东东?不用我多说了,大批的高手会告诉你
    发表于 11-18 22:45

    【自学C++必看】C++编程应用200例

    【自学C++必看】C++编程应用200例
    发表于 08-19 16:08

    C++程序设计原理与实践》(C++之父最新力作)

    `《C++程序设计原理与实践》(C++之父最新力作)`
    发表于 08-19 16:30

    JAVA和C++区别

    不支持多重继承,但允许一个类继承多个接口(extends+implement),实现了c++多重继承的功能,又避免了c++中的多重继承实现方式带来的诸多不便。 3.数据类型及类 Java是完全面向对象
    发表于 10-10 14:50

    C++笔记010:C++C的扩展——register关键字增强

    的地址在C语言里面是会出错的。同样的代码我们放到C++编译环境下,发现编译是通过的!在C++中依然支持register关键字,C++编译器有自己的优化
    发表于 08-11 12:34

    Java和C++的区别

    不支持多重继承,但允许一个类继承多个接口(extends+implement),实现了c++多重继承的功能,又避免了c++中的多重继承实现方式带来的诸多不便。 3.数据类型及类 Java是完全面向对象
    发表于 09-13 16:02

    控件的快捷方式禁用

    请问:多列列选框如何通过程序禁用快捷方式,目前只能手动设置
    发表于 06-03 18:28

    学习c++的经验分享!

    上,要学会控制集成开发环境,还要学会用命令行方式处理程序;25.和别人一起讨论有意义的C++知识点,而不是争吵XX行不行或者YY与ZZ哪个好;26.请看《程序设计实践》,并严格的按照其要求去做;27.
    发表于 10-08 03:46

    如何学习C++,如何学好C++

    最近,很多学员都给我发邮件问我应该如何学习C++,如何学好C++?那么作为一个从C语言小白摸爬滚打、入坑无数到成长为如今的高级C++游戏开发工程师、高级
    发表于 08-20 06:27

    C语言C++运用

    很多同学在大学都学过CC++,那么CC++就业怎么样?薪资高吗?小编今天就给大家详细解读一下。学c++ 好不好?
    发表于 11-25 10:47

    学习C++的方法以及C++的就业方向

    学习方向:嵌入式+人工智能嵌入式是一门技术学习目标1.嵌入式开发概述;(面向对象在嵌入式开发中角色)2.嵌入式Linux C++编程;(C++概述、C++学习方法、C++开发工具)3.
    发表于 12-24 07:32

    为什么要用C++?

    为什么要用C++?1.面向对象的好处太多了,这点我就不用细说了2.现在的主流单片机有很大一部分是ARM内核,(其中最重要的是STM32和NXP的LPC系列),而ARM对C++的支持还是非常给力
    发表于 02-07 06:07

    C/C++中两种宏实现方式

    #ifndef的方式受C/C++语言标准支持。它不仅可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件(或者代码片段)不会被不小心同时包含。
    的头像 发表于 04-19 11:50 234次阅读