我在某處讀到snprintf比ostringstream快。有沒有人有任何經驗呢?如果是的話爲什麼它更快。爲什麼snprintf比ostringstream更快?或者它是什麼?
回答
std::ostringstream
不是要求要慢一些,但實施時一般比較慢。 FastFormat's website has some benchmarks。
流的標準庫設計支持遠遠超過snprintf
。該設計旨在具有可擴展性,並且包含由公開公開方法調用的方法。這允許你從一個流類派生出來,並保證如果你超載了protect
ed方法,你將得到你想要的行爲。我相信編譯器可以避免virtual
函數調用的開銷,但我不知道有任何編譯器。
此外,流操作通常在內部使用可增長的緩衝區;這意味着相對較慢的內存分配。
這很有可能是因爲sprintf
是用匯編編寫的CRT的一部分。 ostringstream
是STL的一部分,可能更通用一些,並且有OOP代碼/開銷來處理。
我非常強烈地懷疑有人在彙編中實現了`sprintf`,除了可能作爲一個練習受虐狂。一直回到UNIX V6,C運行時庫本身已經被編寫成C語言(除了一些很少用C語言編寫的東西,比如`setjmp`)。 – zwol 2012-09-19 15:42:09
絕對這是特定於實現的。
但是,如果你真的想知道,寫兩個小程序,並比較它們。您需要包含您想要的典型用法,這兩個程序需要生成相同的字符串,然後使用分析器查看時序信息。
然後你就會知道。
我知道printf家族函數比相應的C++函數(cout,cin和其他流)快的原因之一是後者進行類型檢查。由於這通常涉及一些重載操作員的請求,因此可能需要一些時間。實際上,在編程競賽中,爲了這個原因,通常建議您使用printf等而不是cout/cin。
有些人可能會告訴你,函數不能比彼此更快,但他們的實現可以。這是對的,我想我會同意。
除了基準以外,您不可能注意到其中的差異。 C++流一般趨於的原因是它們更加靈活。靈活性通常是以時間或代碼增長爲代價的。
在這種情況下,C++流基於流緩衝區。流本身就是保持格式化和錯誤標誌的地方,並調用C++標準庫的正確i/o
構面(例如,用於打印數字的num_put),將值格式化良好的值打印到基礎流中連接到C++流的緩衝區。
所有這些機制 - 方面和緩衝區都是通過虛函數實現的。雖然確實沒有標記請注意,這些函數必須被實現爲比cStdio掛件慢,這實際上會使它們比通常使用c stdio函數稍慢(我基準了一段時間之前用gcc/libstdC++和事實上注意到一個放緩 - 但你幾乎沒有注意到在日常使用)。
有一個問題可能是由ostringstream
增加的類型安全帶來額外的開銷。不過,我還沒有做過任何測量。
我們用sprintf(使用靜態分配的緩衝區)替換了內部循環中的一些stringstream,這在msvc和gcc中都有很大的不同。我想,這個代碼的動態內存管理:
{ char buf[100]; int i = 100; sprintf(buf, "%d", i); // do something with buf }
比
{ std::stringstream ss; int i = 100; ss << i; std::string s = ss.str(); // do something with s }
簡單多了,但我很高興與stringstreams的整體性能。
是的,如果你用Visual C++ 5.0在幾百萬個數字上運行下面的函數,第一個版本的時間大約是第二個版本的兩倍,併產生相同的輸出。
將緊密循環編譯爲.exe文件並運行Windows時,「我是如何調查大多數性能好奇心的。 (`timethis'可在網上找到)
void Hex32Bit(unsigned int n, string &result)
{
#if 0
stringstream ss;
ss
<< hex
<< setfill('0')
<< "0x" << setw(8) << n
;
result = ss.str();
#else
const size_t len = 11;
char temp[len];
_snprintf(temp, len, "0x%08x", n);
temp[len - 1] = '\0';
result = temp;
#endif
}
- 1. 什麼是更快,爲什麼?
- 2. 什麼比innerHTML更快?
- 3. 惡意js?或者它是什麼
- 4. 流媒體?或者它是什麼?
- 5. REGEXP上這就是爲什麼或者這就是爲什麼
- 6. 回聲爲什麼比打印更快?
- 7. 爲什麼\%(\)在Vim中比\(\)更快?
- 8. 爲什麼Neo4j比SQL更快
- 9. 爲什麼VertexBuffer比DynamicVertexBuffer更快
- 10. 爲什麼BLE 4.2比BLE更快4.1
- 11. 爲什麼file_get_contents()比使用fsock_open()更快?
- 12. 爲什麼String.IsNullOrEmpty比String.Length更快?
- 13. 爲什麼Unix /終端比R更快?
- 14. 爲什麼order()比sort.list()更快?
- 15. 爲什麼DataContractSerializer比xmlSerializer更快?
- 16. 爲什麼array.index比array.include更快?
- 17. 爲什麼Core Data比SQLite更快
- 18. 爲什麼const int比const int&更快?
- 19. 爲什麼HashMap比HashSet快?
- 20. 爲什麼不std :: noskipws工作,或者它應該做什麼?
- 21. 什麼是更快的Flash或Silverlight?
- 22. 哪個更快:char(1)或者tinyint(1)?爲什麼?
- 23. 什麼是進程/收割者,爲什麼它不工作?
- 24. Maven快照究竟是什麼,爲什麼我們需要它?
- 25. 爲什麼macOS系統打印比Chrome或lpr更快?
- 26. 爲什麼requestAnimationFrame比setInterval或setTimeout更好
- 27. C snprintf()的C#模擬是什麼?
- 28. 哪一個是更快,爲什麼
- 29. 智威湯遜。爲什麼它比oAuth更好,簽名是什麼?
- 30. angular4中的Renderer2是什麼?爲什麼它比jQuery更受歡迎?
哇 - 我有一段時間沒去過馬修威爾遜的網站 - 看起來他過去幾個月都很忙... – 2009-01-15 01:52:18
FastFormat測試是有偏見的。下載代碼後,您會看到snprintf()基準測試會調用一個名爲fastformat_util_snprintf()的函數,該函數包含一些可能會拋出測試的包裝代碼。但是你是對的,內存管理可能是ostringstream變慢的原因。 – Max 2009-01-16 11:13:26
感謝您查看代碼。我只看過漂亮的圖表。 – 2009-01-20 09:10:05