跳轉到內容

最佳化程式碼速度/簡介

來自華夏公益教科書

最佳化是指程式碼調整過程,旨在提升某些方面:例如速度、記憶體消耗、輸入/輸出(磁碟讀寫或網路讀寫)等。在數學中,最佳化意味著找到效能最佳的值。在計算中,由於程式非常複雜,通常無法在數學意義上最佳化速度。因此,這個術語通常被用來指代朝著一個或多個方面提升效能的方向發展。

本文將重點介紹最佳化程式碼以使其更快地執行。然而,正如您稍後將看到的那樣,這可能需要在其他方面最佳化程式碼。此外,程式設計師在嘗試最佳化程式的某個方面時,通常是為了提高速度。

目標受眾

[編輯 | 編輯原始碼]

本文的目標受眾是軟體開發人員,主要是至少掌握一門程式語言,能夠編寫中等複雜程度程式的程式設計師。如果您有興趣參與軟體開發的世界,請參考開源教學網站,特別是文章"如何開始貢獻或使用開源軟體"。請注意,並非所有軟體開發人員都是程式設計師,無論是那些將積極程式設計作為其工作定義的一部分的開發人員,還是那些有資格編寫原始碼的開發人員。該文章和該網站上維護的書籍提到了關於學習如何程式設計的資源,如果您有興趣,可以參考這些資源。

然後,只有這樣,您才能回到這本華夏公益教科書。

為什麼要最佳化?

[編輯 | 編輯原始碼]

那麼,為什麼要最佳化呢?如果您已經使用了一段時間計算機系統,並嘗試過不太“完善”的軟體應用程式,那麼您很可能遇到過應用程式讓您感到困擾的地方:啟動時間過長;行為與預期不符;存在錯誤;執行看似微不足道的操作需要很長時間;無法取消操作;錯誤訊息含糊不清,無法解釋如何克服問題;程式無法退出;導致資料丟失;等等。所有這些問題都可能讓您感到困擾和厭煩,使您感到不愉快。儘管現代計算機的計算能力和儲存容量以及多功能性得到了應有的尊重,但計算機仍然是其主人(有感知能力的人類)手中的工具。因此,它們應該儘可能快、正確和徹底地執行其主人指示它們執行的功能,讓我們能夠無縫地繼續使用它們來完成自己的工作或娛樂,或者換句話說,從計算中休息一下,做些其他事情,而不是與計算機作鬥爭。

一個能很好地執行其功能的軟體元件或應用程式,具有很高的質量,並讓使用者感到快樂和掌控。另一方面,一個速度太慢、錯誤太多、不穩定性太高等的軟體元件缺乏必要的質量,會讓使用者感到沮喪、痛苦、憤怒或失去掌控。沒有人喜歡這種感覺。

如何建立和維護在各個方面都具有高品質的軟體超出了本文的範圍,有興趣的讀者可以參考之前由本文作者創作的關於此主題的一篇文章,標題為"什麼是高質量軟體?"。本文將重點介紹如何使我們的軟體快速響應,這是質量的一個重要方面,有時會被忽略。

如果我們的程式速度太慢或響應遲緩(後者也被稱為“遲鈍”),那麼我們的使用者會感到沮喪,或者在程式執行時感到無聊,並去做其他事情。在這種情況下,我們通常應該最佳化程式,以確保其執行速度足夠快,或響應足夠快,從而讓使用者感到更快樂,因為他們不必等待程式完成或響應。我們在下面將更詳細地介紹這方面的更多內容。

哪些程式需要最佳化?

[編輯 | 編輯原始碼]

有一些型別的程式需要最佳化。其中一類是即時程式。儘管存在普遍的誤解,但這些程式並不一定需要非常快。相反,即時程式是指必須在專門用於該事件的特定時間限制內對某些事件做出響應的程式。例如,如果使用者在文字處理程式視窗內按下鍵盤鍵,它應該相對快速地顯示該字元。5 秒的延遲是不可接受的,因此文字處理程式是一種具有某些即時約束的應用程式。

即時系統中的某些部分可能需要最佳化。然而,一旦時間低於所需的延遲,就無需進行其他最佳化。(至少在測試證明它再次超出限制之前。)

其他需要最佳化的程式是那些速度不夠快的程式。此類程式的例子包括人工智慧程式、遊戲、多媒體程式、虛擬機器和程式語言直譯器,或任何型別的公開可用庫或模組,其“野外”使用可能需要它非常快。

當然,另一類此類程式是速度太慢或被認為速度太慢的程式。通常沒有內在原因導致它們速度慢,而且往往沒有任何東西可以阻止此類程式變得更快。此類被認為速度太慢的程式應該被最佳化以使其執行得更快。

然而,其他程式本質上是緩慢的。例如,金鑰強化演算法專門設計為速度緩慢,並且沒有已知的捷徑。另一個例子是,透過 12 Mbit/s“USB 全速”埠複製 8 GB 資料本質上需要超過 1 小時,這是由於硬體的限制。

何時最佳化?

[編輯 | 編輯原始碼]

經驗法則是,如果程式的速度與預期速度相比不夠快,那麼就應該最佳化程式。一個常見的誤解是,如果程式現在速度不夠快,那麼隨著硬體變得更快,程式的執行速度也會更快。然而,情況並非總是如此。

如果您的程式速度慢,通常是因為程式碼沒有最佳化(例如,它使用了次優演算法)。雖然更好的硬體通常會提高效能,但並不能保證速度會有明顯提高。此外,雖然硬體速度的進步使程式設計師能夠編寫更浪費的程式碼(參見Paul Graham 的“百年語言”文章),但有些程式仍然過於緩慢。

在現代環境中編寫程式時,應該使其速度足夠快。有些人聲稱,我們在單核心處理器方面已經達到了摩爾定律的終點,我們不能指望單處理器的單執行緒程式執行速度更快。無論如何,即使程式在高階平臺上執行良好,它可能仍然需要在舊的硬體上執行。

我們都見過這樣的情況:計算機速度越來越快,但軟體執行速度卻經常變得更慢,除非硬體升級。 所謂的“蓋茨定律”聲稱,由於各種原因,商業程式的速度每 18 個月下降一半。眾所周知,各種版本的 DOS 作業系統在 PC XT 和 286 上執行良好,正如一位記者當時所說,英特爾 386 是一款“精幹高效的 DOS 機器”。另一方面,Microsoft Windows 3.0 和 Microsoft Windows 3.1 已經需要一臺快速的 486 計算機才能流暢執行,而 Windows 95 在那裡幾乎無法使用,需要一臺奔騰計算機。Windows XP 在奔騰機器上已經執行緩慢,需要高階的奔騰 III 或奔騰 4 計算機。 Windows Vista 需要比 Windows XP 更多的硬體資源,以至於目前許多計算機都無法舒適地執行它。

現在,雖然直接針對 CPU 和記憶體(可能還有硬碟)執行的軟體模擬速度比以前快得多,但系統本身的響應速度似乎並沒有明顯提高。

何時不最佳化?

[編輯 | 編輯原始碼]

如果所討論的程式執行速度足夠快,則不應進行最佳化。但是,如果它還必須在較慢的硬體上執行良好,處理更大的負載或在資源較少的情況下正常工作,則可能需要根據這些要求進一步最佳化程式。

令人驚訝的是,分析通常會發現,對特定程式應用特定最佳化技術會使其變慢。在這種情況下,應恢復到程式的先前“未最佳化”版本。

最佳化與模組化和可讀性

[編輯 | 編輯原始碼]

最佳化可能會對模組化和可讀性等程式碼質量因素產生負面影響。例如,考慮 GMP(GNU 多精度) 的開發人員在 他們的手冊 中寫的內容

GMP 的速度是透過使用全字作為基本算術型別、使用複雜的演算法、為許多不同 CPU 的最常見內部迴圈包含經過精心最佳化的彙編程式碼以及普遍強調速度(而不是簡單性或優雅)實現的。

還要考慮,短 函式方法 被認為優於較長的方法,以允許更大的程式碼重用、測試和自文件化。(請參閱 “提取方法”重構模式)。但是,函式或方法呼叫被認為是相對昂貴的操作,因此這種額外的程式碼質量可能會使程式變慢。

因此,不難想象,一個希望節省一些額外週期的開發人員會將一個僅使用一次或幾次的函式合併到其呼叫者程式碼中(或使用 或預處理階段(如果可能)合併其程式碼),從而使程式碼模組化程度降低。

類似地,高度最佳化的程式碼也可能變得更加難以閱讀。例如,C 預處理器的宏以使使用它們的程式碼難以閱讀而聞名。我聽說 一些抱怨OpenSSL 的程式碼(基於預處理器宏、相同名稱的靜態函式和大量程式碼生成)由於這些事實而非常難以理解和遵循。

類似的抱怨不斷針對 perl5 的 XS 表達,它是用於在 ANSI C 和其他更低階語言中建立子例程的介面。該 API 的設計儘可能高效和快速,因此難以學習、理解和遵循。

華夏公益教科書