點擊上方“C語言與CPP編程”,選擇“關注/置頂/星標公眾號”
干貨福利,第一時間送達!
最近有小伙伴說沒有收到當天的文章推送,這是因為微信改了推送機制,確實會一部分有小伙伴刷不到當天的文章,一些比較實用的知識和信息,錯過了就是錯過了。所以建議大家加個星標??,就能第一時間收到推送了。
在?C++ 開發中,錯誤處理是一個至關重要的組成部分。不同的錯誤處理策略不僅會影響代碼的可讀性和可維護性,還會對應用程序的性能產生重大影響。為了深入了解各種錯誤處理技術在性能上的差異,本文作者進行了基準測試。本次測試旨在提供清晰的性能洞察,幫助開發者在實際應用中選擇最合適的錯誤處理方法。
原文鏈接:https://johnfarrier.com/c-error-handling-strategies-benchmarks-and-performance/
錯誤處理是許多 C++ 應用程序中的關鍵部分,我們也有許多策略可以用來處理錯誤。最近,我想更好地了解 C++ 中各種錯誤處理技術對性能的影響。
我決定對不同的技術進行基準測試,看看它們的性能如何。為此,我使用了 Celero C++ 微基準測試庫,以此清楚地了解每種方法的性能。
例如,std::expected 在可讀性和可維護性方面有很多優點,同時考慮它的性能特征也很重要。通常,std::expected 比 exception(異常)更有效,因為它避免了堆棧展開的開銷,而這在性能關鍵型應用程序中可能非常重要。
我構建了一個基準測試來比較以下 C++ 錯誤處理策略:
●?使用返回 true/false 表示成功/失敗(Baseline)
●?使用錯誤代碼(Error Code)返回值
●?使用 std::expected
●?使用 std::optional
●?使用 std::variant
●?使用 Callback
●?使用 std::exception
該 C++ 錯誤處理基準測試是用 Celero C++ 微基準測試庫構建的。關于 C++ 錯誤處理基準測試的具體代碼可查看:https://github.com/DigitalInBlue/celeroErrorHandlingBenchmark。
以下是原始輸出結果:

為簡化起見,以下是這些技術相對性能的精簡版本:

在基線(Baseline) 歸一化性能的情況下,使用 std::expected 慢約 2.1 倍。
排除 std::exception 后,C++ 錯誤處理基準測試結果表明,各種錯誤處理技術在性能上存在顯著差異:

● Baseline(基線) :基線方法是返回 true 或 false,是最快的技術,平均每次迭代耗時 0.00324 微秒。
● std::expected:使用 std::expected 比基線慢約 2.18 倍,平均每次迭代耗時 0.00707 微秒。
● Error Code(錯誤代碼):使用 Error Code 幾乎與基線一樣快,平均每次迭代耗時 0.00329 微秒。
● Optional:使用 std::optional 較慢,平均每次迭代耗時 0.00578 微秒,比基線慢約 1.78 倍。
● Variant:使用 std::variant 是非異常技術中最慢的,平均每次迭代耗時 0.00919 微秒,比基線慢約 2.83 倍。
● Error Callback(錯誤回調):使用 Error Callback 對性能影響的中等,平均每次迭代耗時 0.00429 微秒,比基線慢約 1.32 倍。
● Exception(異常):使用 std::exception 明顯比所有其他技術都慢,平均每次迭代耗時 160.59420 微秒,比基線慢約 49,540 倍。
(1)可讀性與性能之間的權衡:
雖然 std::expected 和類似結構(如 std::optional,std::variant)提供了更具可讀性和可維護性的代碼,但同時也帶來了相應的性能成本。在可讀性和可維護性至關重要、而對性能要求不高的應用程序中,這些結構具有優勢;然而,在對性能要求較高的應用程序中,可能更偏向于使用簡單的錯誤處理方法。
通常情況下,我們建議在整個應用程序中選擇一種錯誤處理方法,但有時可能也需要一種“默認”的錯誤處理方式(如使用 std::expected)和一種在特定情況下使用的“高性能”替代方案。
(2)不同情況下的錯誤處理策略:
高性能系統:對于需要高性能的系統,如實時系統或高頻交易平臺,應首選開銷最小的錯誤處理技術,如返回代碼或錯誤回調。
現代 C++ 應用程序:受益于現代 C++ 范式且對性能要求不太高的應用程序,可以用 std::expected 和 std::optional 獲得更好的代碼表達能力。
(3)Exception(異常)的影響:
異常帶來的巨大開銷(比基線慢 49,540 倍)凸顯了為何在性能關鍵的代碼中避免使用異常的原因。異常處理期間的堆棧展開過程會導致相當大的延遲。不過,異常對于處理應用程序中對性能要求較低部分的意外或罕見錯誤情況非常有用。
(4)基準環境和條件:
需要注意的是,基準測試可能會受到運行環境的影響(例如,CPU,編譯器優化等)。本文提供的結果是針對特定基準條件下的結果,應根據你的具體應用進行驗證。
(5)內存使用注意事項:
雖然運行時性能至關重要,但內存使用也是一個重要因素。基準測試結果表明,大多數技術(不包括例外情況)的內存使用情況相似,這說明錯誤處理方法的選擇對內存占用的影響可能微乎其微。
(6)可組合性和集成性:
std::expected 和 std::optional 與其他現代 C++ 特性集成得很好,可能會簡化復雜的錯誤傳播場景。
根據基準測試結果,C++ 錯誤處理技術的選擇應由應用程序的具體需求決定。以下是一些建議:
●?性能關鍵型應用:使用簡單的錯誤處理方法,如返回代碼或錯誤回調,盡量減少開銷。
●?現代、可維護的代碼:使用 std::expected 或 std::optional 以提高代碼的清晰度和可維護性,尤其是在可以接受輕度性能開銷的情況下。
●?異常處理:將異常保留給意外或不常發生的錯誤,因需要全面的錯誤信息,所以巨大的開銷也算合理。
這些 C++ 錯誤處理基準測試強調了根據應用程序的性能需求選擇正確錯誤處理技術的重要性。盡管 std::expected 和其他現代 C++ 特性提供了更好的可讀性和可維護性,但它們對性能的影響也不容忽視,尤其是在對性能要求極高的應用程序中。
本文轉自公眾號“CSDN”,ID:CSDNnews
—— EOF —— 你好,我是飛宇。日常分享C/C++、計算機學習經驗、工作體會,歡迎點擊此處查看我以前的學習筆記&經驗&分享的資源。
我組建了一些社群一起交流,群里有大牛也有小白,如果你有意可以一起進群交流。
歡迎你添加我的微信,我拉你進技術交流群。此外,我也會經常在微信上分享一些計算機學習經驗以及工作體驗,還有一些內推機會。
加個微信,打開另一扇窗
經常遇到有讀者后臺私信想要一些編程學習資源,這里分享 1T 的編程電子書、C/C++開發手冊、Github上182K+的架構路線圖、LeetCode算法刷題筆記等精品學習資料,點擊下方公眾號會回復"編程"即可免費領取~
感謝你的分享,點贊,在看三連??