提升 Python 程式效能的 6 個技巧

笑虎發表於2015-02-04

Python是一個很酷的語言,因為你可以在很短的時間內利用很少的程式碼做很多事情。不僅如此,它還能輕鬆地支援多工,比如多程式等。Python批評者有時會說Python執行緩慢。本文將嘗試介紹6個技巧,可加速你的Python應用程式。

1.讓關鍵程式碼依賴於外部包

雖然Python讓許多程式設計任務變得容易,但它可能並不總能為緊急的任務提供最佳效能。你可以為緊急的任務使用C、C++或機器語言編寫的外部包,這樣可以提高應用程式的效能。這些包都是不能跨平臺的,這意味著你需要根據你正在使用的平臺,尋找合適的包。簡而言之,這個方案放棄了一些應用程式的可移植性,以換取只有在特定主機上直接程式設計才能獲得的程式效能。這裡有一些你應該考慮加入到你的“效能兵工廠”的包:

這些包以不同的方式提高效能。例如,Pyrex能夠擴充套件Python所能做的事情,例如使用C的資料型別來讓記憶體任務更加有效或直接。PyInIne讓你在Python應用程式中直接使用C程式碼。程式中的內聯程式碼單獨編譯,但它在利用C語言所能提供的效率的同時,也讓所有的程式碼都在同一個地方。

2.排序時使用鍵(key)

有很多老的Python排序程式碼,它們在你建立一個自定義的排序時花費你的時間,但在執行時確實能加速執行排序過程。元素排序的最好方法是儘可能使用鍵(key)和預設的sort()排序方法。例如,考慮下面的程式碼:

每一個例項中,根據你選擇的作為key引數部分的索引,陣列進行了排序。類似於利用數字進行排序,這種方法同樣適用於利用字串排序。

3.優化迴圈

每種程式語言都會強調需要優化迴圈。當使用Python的時候,你可以依靠大量的技巧使得迴圈執行得更快。然而,開發者經常漏掉的一個方法是:避免在一個迴圈中使用點操作。例如,考慮下面的程式碼:

每一次你呼叫方法str.upper,Python都會求該方法的值。然而,如果你用一個變數代替求得的值,值就變成了已知的,Python就可以更快地執行任務。優化迴圈的關鍵,是要減少Python在迴圈內部執行的工作量,因為Python原生的直譯器在那種情況下,真的會減緩執行的速度。

(注意:優化迴圈的方法有很多,這只是其中的一個。例如,許多程式設計師都會說,列表推導是在迴圈中提高執行速度的最好方式。這裡的關鍵是,優化迴圈是程式取得更高的執行速度的更好方式之一。)

4.使用較新版本的Python

在網上搜尋Python資訊,都會發現無數人在問,從Python一個版本遷移到另一個版本的問題的資訊。一般來說,Python的每一個版本都包含了能讓其比上個版本執行更快的優化。版本遷移的限制因素是,你喜歡的那些庫是否已經遷移到Python的較新版本。相比於詢問是否應該進行版本遷移,關鍵問題是確定一個新版本什麼時候有足夠的支援,以保證遷移的可行性。

你需要驗證你的程式碼仍然執行。你需要在Python的新版本下使用你獲得的新庫,然後檢查你的應用程式是否需要重大改變。只有在你作出必要的更正之後,你才會注意到版本之間的差別。然而,如果你正好確保你的應用程式能在新版本下執行,而不需要任何改變,你可能會錯過那些版本升級帶來的新特性。一旦你進行了遷移,你應該為你的新版本下的應用程式寫一個說明,檢查有問題的地方,並且優先考慮利用新版本的特性去更新那些地方。這樣使用者將會在升級的過程中更早的看到一個更大的效能提升。

5.嘗試多種編碼方法

如果每次你建立一個應用程式都是用相同的編碼方法,幾乎肯定會導致一些你的應用程式比它能夠達到的執行效率慢的情況。作為分析過程的一部分,你可以嘗試一些實驗。例如,在一個字典中管理一些元素,你可以採用安全的方法確定元素是否已經存在並更新,或者你可以直接新增元素,然後作為異常處理該元素不存在情況。考慮第一個編碼的例子:

這段程式碼通常會在myDict開始為空時執行得更快。然而,當mydict通常被資料填充(或者至少大部分被充填)時,另一種方法效果更好。

兩種情況下具有相同的輸出:{‘d’: 4, ‘c’: 4, ‘b’: 4, ‘a’: 4}。唯一的不同是這個輸出是如何得到的。跳出固定的思維模式,創造新的編碼技巧,能夠幫助你利用你的應用程式獲得更快的結果。

6.交叉編譯應用程式

開發者有時會忘記,電腦實際上是不懂任何用於建立現代應用程式的語言,電腦所能懂得是機器程式碼。為了能在電腦上執行應用程式,你使用一個應用將人類可讀的程式碼你轉換成計算機能理解的。有時候用一種語言,比如Python,寫一個應用,並用另一種語言,比如C++,執行它,從效能的角度來看是有意義的。這取決於你想要應用程式去做什麼,以及主機系統可以提供的資源。

一個有趣的交叉編譯器,Nuitka,可以將你的Python程式碼轉換為C++程式碼。這麼做的結果是,你可以在原生模式下執行應用程式,而不是依靠直譯器。根據平臺和任務,你可以看到一個顯著的效能提升。

(注意:Nuitka目前還處於測試階段,所以用它來產品程式時需要小心。實際上,目前最好將其用於實驗。現在也有一些關於交叉編譯是否是得到更好效能的最佳方式的討論。開發者已經利用交叉編譯好幾年了,目的是實現特定的目標,比如更好的應用程式的速度。記住,每一個解決方案都會有得有失,你應該在將一個解決方案用於生產環境之前就好好考慮一下得失情況。)

在使用一個交叉編譯器時,要確保它支援你使用的Python的版本。Nuitka支援Python2.6、2.7、3.2和3.3。想讓這個方案發揮作用,你需要一個Python直譯器和一個C++編譯器。Nuitka支援多種C++編譯器,包括Microsoft Visual Studio、MinGW 和 Clang/LLVM。

交叉編譯也可能帶來一些嚴重的負面影響。例如,當利用Nuitka工作時,你會發現即使一個小程式也能消耗很大的硬碟空間,這是因為Nuitka使用大量的動態連結庫(DLLs)實現Python的功能。所以當你面對一個資源有限的系統時,這個方案可能不會很好的起作用。

總結

這六個技巧中的任意一個,都可以幫助你創造更快的Python程式。但任何技巧都不是萬能的,不能每次都起作用。有些技巧在Python的特定版本下比其他技巧的更有效——甚至系統平臺也能影響它們的效果。你需要配置你的應用,確定哪個地方讓其執行緩慢,然後嘗試似乎能最好的解決這些問題的一些技巧。

打賞支援我翻譯更多好文章,謝謝!

打賞譯者

打賞支援我翻譯更多好文章,謝謝!

提升 Python 程式效能的 6 個技巧

相關文章