前言
經常有人說iostream的速度慢,io流比stdio的慢多了。但是有人測試過的,iostream的速度是超過stdio的。
測試結果
/* c */
#include
int main()
fclose(stream);
printf("%u\n", sum);
return 0;
}/* c++ */
#include
#include
using namespace std;
int main()
cout << sum << endl;
return 0;
}random.data中為100000個0-32767的隨機數
c版本平均用時0.64s,c++平均用時0.58s
於是又把這陳芝麻爛穀子事拿出來研究。單步vc10/11(用後者是因為新版加入了chrono方便計時),cout輸出一段字串的呼叫順序如下:
operator<< => sputn => xsputn => overflow => _fputc => fputc
cout封裝了fputc乙個字元乙個字元的輸出,而win下預設不給stdout開buffer,於是造成cout輸出字串極度緩慢,杯具出現了
想起執行緒安全性問題。cout雖然執行緒安全(原文:但是輸出的字元是混在一起的,我猜想也是cout封裝fputc而在fputc裡加鎖的原因。
看printf()的原始碼:
va_start(arglist, format);
_lock_str2(1, stdout);
__try
__finally
首先將stdout整體加鎖,然後給stdout開了乙個臨時buffer,輸出後再重新整理,顯然要比cout快得多。
測試用了fstream,檔案指標在win下是預設開buffer的,於是給cout手動開buffer,前後測試結果如下:
未開buffer:
開了buffer:
可以看到未開buffer時cout的用時比printf慢數十倍,開buffer後的用時與printf已經十分接近(cout繫結stdout,給cout開buffer就等於給printf開buffer),造成的差異應該是每個字元分別加鎖的緣故。另外printf用%s輸出比直接輸出快,大概是因為直接輸出的話解析格式字串時每個字元都要判斷format[n]=='%'
這是g++ mingw-w64的測試結果:
未開buffer:
開了buffer:
stdlibc++使用了不同的封裝方式,未開buffer時兩者速度已經較為接近,開buffer後已經超過用printf直接輸出。
關於g++和vc的速度比較,除了原生64位以外,crt也有差距,畢竟vc是微軟自己的東西
注:mingw的cout.rdbuf()->pubsetbuf似乎有問題,改用setvbuf
附虛擬機器下fedora 16(g++ 4.6.2)測試結果(linux預設給stdout開buffer)
tip:
關於cout輸出慢,可能是buffer重新整理的問題 把endl換成'\n'就會快上許多了。
關於Exosip的效率問題
最近一段時間利用boost多執行緒和ace多執行緒,對exosip的效能進行了比較深入一些的測試。現將測試方法分享一下,在此拋磚引玉,希望大家也可以提供一些建議。首先,原始的exosip只有2個執行緒,乙個做的事情很簡單,是等待事件,另外乙個執行緒非常忙,要做事務狀態的轉換,要收訊息,要解析訊息,要...
關於 迴圈 效率的問題
今天寫到迴圈邏輯,糾結於是用更少的迴圈呼叫函式還是用更少的函式,多迴圈兩次。於是做了個實驗,發現基於c的lua,函式呼叫的代價果然很高。local tb local max 10000000 for i 1,max do tb i i endfunction check i,max if tb i ...
關於for while的效率問題
首先比較for與while的效率問題必須保證迴圈次數一致 下面簡單的分析for與while的效率問題就從最簡單的無限迴圈開始,其餘相同 for while 1 這兩句都實現了無限迴圈的功能,使用gcc編譯成彙編 為 for file for.c text globl main type main,f...