理解 C++/最佳化
|
現代的 編譯器 通常具有設定以在編譯過程中自動執行最常見的最佳化,這通常大大減少了程式設計師可能需要考慮的最佳化數量。現代編譯器通常利用對特定 系統 和 架構 的瞭解,以及多年的最佳化研究成果,以進一步提高效能和最小化資源使用。這種最佳化最好留給編譯器,因為手動操作可能會導致膨脹或效能成本。
當你遇到一個問題時,你會嘗試找到解決問題的方案。有時解決方案很簡單,而有時可能的解決方案並不那麼簡單,可能需要規劃並決定採取哪些步驟。演算法 是程式設計師用來解決問題的詳細步驟。演算法研究不斷尋找更簡單、更快速的方法來解決問題,重新考慮和減少問題,並將問題分解為更易於管理的問題。最佳化在演算法程式設計中非常重要,但並非所有 演算法 都能從最佳化中獲益。
諸如在列表中搜索名稱或對名稱進行排序等問題可以透過演算法解決。例如,排序演算法從 1950 年代開始開發,新的解決方案仍在不斷被發現。使用哪種演算法的選擇取決於時間或空間哪個更重要。如果程式速度比節省記憶體使用更重要,通常可以在預先儲存一些值,以減少後續的計算量。同樣,如果給定時間重新計算所有值,演算法可以節省大量空間。
通常,一個程式可以透過簡單地意識到它做了太多事情來最佳化。由於解決問題的方法有很多,一種解決方案可能有效,但與其他方法相比效率極低,就像第一個 排序演算法,即 氣泡排序 一樣。如果使用樸素方法,涉及搜尋列表或 二叉樹 的問題可能比實際需要的速度慢很多倍。如果程式的一部分執行速度太慢而無法可靠地執行,研究手頭的問題以尋找更快的方法可能值得嘗試。
冗餘會增加解決問題所需的大小和時間。現代編譯器通常可以消除一些冗餘,例如從未使用過的變數、函式、值和語句,以及常量變數、值和計算結果。但是,演算法的複雜性會降低編譯器最佳化過程消除冗餘的有效性。
- 冗餘的示例
int foo = 0, bar = 2+2*4, baz = 9;
if (foo) {
while (foo) {
...
}
}
if (bar) {
do_loop(bar);
}
void do_loop(int bar) {
while (bar) {
...
}
return;
do_nothing();
}
程式設計師減少或消除冗餘的常用策略
- 在建立小函式時假設有效狀態。
- 將驗證測試限制在不受你控制的事件中,例如使用者輸入、計算機資源和外部函式。
最佳化也反映在程式碼的有效性上。如果你可以使用一個已有的大量程式設計師可以訪問的程式碼庫/框架,你可以期望它更少錯誤,並針對你的特定需求進行了最佳化。
其中一些程式碼庫以庫的形式提供給 C++ 程式設計師。請務必考慮依賴項並檢查實現方式:如果在沒有考慮的情況下使用,這也可能導致程式碼膨脹和記憶體佔用增加,以及降低程式碼的可移植性。我們將在本書的標準庫部分仔細研究其中的一些庫。