關於iostream的效率問題

2021-09-08 10:07:01 字數 1561 閱讀 1455

前言

經常有人說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...