恰好之前研究過這塊,所以借助本文,分析下這個問題(無意于語言之爭,單純是從技術(shù)角度)。
眾所周知,C++兼容了C的所有功能,顯然從所有角度去對比分析是不現(xiàn)實(shí)的,所以本文從我們常用的輸入輸出即標(biāo)準(zhǔn)流(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?"?<(end-start).count()<"ms"?<(end-start).count()<"ms"?<>n; } },[](){ freopen("./data","r",stdin); intn=0; for(inti=0;i
編譯,運(yùn)行之后,輸出如下:
cincost686ms scanfcost189ms
從上述輸出來看,cin的耗時是scanf的3倍多,果真如此么?
sync_with_stdio
C++性能真的差C這么多嗎?直接顛覆了對C++的認(rèn)知,即使性能真的低,也得知道為什么低吧,于是開始研究,發(fā)現(xiàn)C++為了兼容C,在C標(biāo)準(zhǔn)流(stdio)和C++標(biāo)準(zhǔn)流(iostrem)保持同步,這樣就可以混合使用C和C++風(fēng)格的I/O,且能保證得到合理和預(yù)期的結(jié)果,而正是這個同步導(dǎo)致C++在cin性能上有損失。如果禁用同步,則允許C++流擁有自己的獨(dú)立緩沖區(qū),這樣性能就會提升很多。
那么是否可以禁用該同步功能呢?
C++提供了一個函數(shù)std::sync_with_stdio,聲明如下:
staticboolsync_with_stdio(bool__sync=true);
如果參數(shù)為false,則代表禁用此同步。從上面聲明可以看出,默認(rèn)情況下__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; }
從上述代碼,進(jìn)一步驗(yàn)證了我們上面的說法,如果禁用了同步功能,則C++流使用自己的緩沖區(qū)buf_cin(此處以cin為例),幾種buffer的定義如下:
typedefcharfake_filebuf[sizeof(stdio_filebuf)] __attribute__((aligned(__alignof__(stdio_filebuf )))); fake_filebufbuf_cout; fake_filebufbuf_cin; fake_filebufbuf_cerr;
好了,截止到現(xiàn)在,我們已經(jīng)搞清楚了為什么C++流性能要慢于C,為了驗(yàn)證是否真的是因?yàn)槭褂昧送焦δ芏鴮?dǎo)致的性能差異,使用std::sync_with_stdio(false)關(guān)閉同步,代碼示例如下:
#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?"?<(end-start).count()<"ms"?<(end-start).count()<"ms"?<>n; } },[](){ freopen("./data","r",stdin); intn=0; for(inti=0;i 編譯,運(yùn)行后,輸出如下:
cincost178ms scanfcost189ms
可以看出禁用同步后,二者的性能基本一致。
既然禁用同步后,C++流的性能與C基本一致,那么是否直接禁用呢?答案是依賴于具體的使用場景。
1、同步的C++流是線程安全的,也就說來自不同線程的輸出可能會交錯,但數(shù)據(jù)不會產(chǎn)生競爭,而如果禁用同步,則可能出現(xiàn)意想不到的結(jié)果。
2、如果禁用了同步功能,輸入輸出順序可能會得不到我們想要的結(jié)果。
#include#include intmain(){ std::cout<"a?"; ??printf("b?"); ??std::cout?<"c?"; ??return?0; }
上述代碼執(zhí)行后,輸出a b c ,符合我們的預(yù)期。
如果加上禁用同步代碼,如下:
#include#include intmain(){ std::sync_with_stdio(false); std::cout<"a?"; printf("b?"); std::cout?<"c?"; return?0; }
編譯、運(yùn)行之后,結(jié)果為a c b,與我們期望的不一致。
結(jié)語
如果使用C編程,那么使用C stdio,而如果使用C++編程,則建議使用C++ I/O。如果在某些特殊場景下,需要混合使用,那么強(qiáng)烈建議不要禁用同步,否則會得到意想不到的結(jié)果。
好了,今天的文章就到這,我們下期見!
審核編輯:彭靜
-
編程
+關(guān)注
關(guān)注
88文章
3639瀏覽量
94026 -
C++
+關(guān)注
關(guān)注
22文章
2114瀏覽量
73882 -
代碼
+關(guān)注
關(guān)注
30文章
4834瀏覽量
69114
原文標(biāo)題:C++性能真的不如C嗎?
文章出處:【微信號:C語言與CPP編程,微信公眾號:C語言與CPP編程】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
C語言實(shí)現(xiàn)面向?qū)ο蟮?b class='flag-5'>方式 C++中的class的運(yùn)行原理
如何提高c和c++的安全編程能力?《C和C++安全編碼》帶你詳細(xì)學(xué)習(xí)
VISUAL C++教程之VISUAL C++的安裝和使用方法
![VISUAL <b class='flag-5'>C++</b>教程之VISUAL <b class='flag-5'>C++</b>的安裝和使用方法](https://file.elecfans.com/web1/M00/7F/3A/o4YBAFwkkXWAI3XbAAMQcR8pLac666.png)
C++程序設(shè)計教程之C++的初步知識的詳細(xì)資料說明
![<b class='flag-5'>C++</b>程序設(shè)計教程之<b class='flag-5'>C++</b>的初步知識的詳細(xì)資料說明](https://file.elecfans.com/web1/M00/89/2B/o4YBAFyJ-q-AYUB7AAVUPZRjpCQ608.png)
C語言與C++相互調(diào)用
![<b class='flag-5'>C</b>語言與<b class='flag-5'>C++</b>相互調(diào)用](https://file.elecfans.com/web1/M00/DB/52/pIYBAGAE-4GAMG1iAABMAgM4a5U248.png)
C++學(xué)習(xí)筆記之c++的基本認(rèn)識
C/C++編譯器的缺省字節(jié)對齊方式
淺談C語言與C++的前世今生
![淺談<b class='flag-5'>C</b>語言與<b class='flag-5'>C++</b>的前世今生](https://file1.elecfans.com/web2/M00/88/B4/wKgaomRwC8yAFS1NAAAhA9uxZyE116.png)
c++入門后如何進(jìn)階
![<b class='flag-5'>c++</b>入門后如何進(jìn)階](https://file1.elecfans.com/web2/M00/8D/5B/wKgaomS52GiAbSMkAAAOAc8d3E0200.jpg)
C++之父新作帶你勾勒現(xiàn)代C++地圖
![<b class='flag-5'>C++</b>之父新作帶你勾勒現(xiàn)代<b class='flag-5'>C++</b>地圖](https://file1.elecfans.com/web2/M00/AD/10/wKgZomU_azGAffwHAAAHSRvJtKU665.png)
c++多行注釋快捷鍵
C++簡史:C++是如何開始的
![<b class='flag-5'>C++</b>簡史:<b class='flag-5'>C++</b>是如何開始的](https://file1.elecfans.com/web2/M00/A9/66/wKgZomUl7m-AHJX6AABuJjgxs14678.png)
評論