用數據告訴你 Python 程式碼比 Java 慢 100 倍!

  • 2019 年 12 月 24 日
  • 筆記

小夥伴們都知道,在系統的軟體開發中,不僅僅是只使用一種語言,也會涉及到不同的語言。

各個語言之間有共性、也有個性。正是這些不同的個性、註定它們會用在不同的場合來解決不同類型的問題。

而程式語言在開發階段中也會存在差異性,在軟體開發這個抽象的概念下,程式語言的差異性主要體現在編碼和編譯以及運行上。

先來看看編譯型語言定義:

編譯型語言首先是將源程式碼編譯生成機器指令,再由機器運行機器碼(二進位)。也就是在運行之前,程式碼已經被翻譯位機器碼了。

再來看看解釋型語言的定義:

解釋型語言的源程式碼不是直接翻譯成機器指令,而是先翻譯成中間程式碼,再由解釋器對中間程式碼進行解釋運行。也就是到機器碼需要兩個步驟,運行前先到中間碼,運行時再編譯成機器碼。

有的小夥伴認為,雖然解釋型程式語言可以讓開發者更快地編寫和測試程式碼,但仍然認為編譯器是值得長期投入的。

編譯型程式碼有兩個明顯的優勢:

  • 每次修改程式碼都可以得到驗證,甚至是在開始運行程式碼之前。
  • 更快的執行速度。根據具體情況,程式碼可能被編譯成非常底層的運行指令。

於是偏愛編譯型語言的小夥伴將 Java 、 Go 和 Python通過比較在處理不同任務時的性能表現,來驗證到底編譯型程式碼的執行速度會比解釋型快多少。

通過程式碼比較 JIT 的性能,後來使用 Python 和 Go 也實現了一遍。

這段程式碼計算 100 的 Fibonacci 數值,每一輪計算 50 次,並列印執行時間(納秒),共計算 200 輪。

三種語言的輸出結果看起來像這樣:

平均值是這樣:

可以看到,在計算 Fibonacci 數值時,Java 比 Go 要慢一些,大概慢 24%,而 Python 幾乎慢了 100 倍,也就是 9458%。

這個結果驗證了對 Java 和 Go 的判斷,但讓我們感到吃驚的是 Python 的表現,它慢得不只是一個數量級,是兩個!

Python 為什麼會花這麼多時間。

很多人關注的是 Python 的易用性,並通過犧牲性能來快速獲得處理結果。

相信數據科學家們都是這麼想的,況且有這麼多現成的庫可以用,為什麼要去找其他的?遲早會有人優化它們的。

第二個原因是很多人沒有比較過不同的實現,因為很多公司在激烈的競爭中忙於做出產品,根本無暇顧及什麼優化不優化。

第三個原因,有一些方式可以讓同樣的 Python 程式碼跑得更快。

把 Python 程式碼編譯一下會如何?

PyPy 是 Python 的另一個實現,它本身就是使用 Python 開發的,包含了一個像 Java 那樣的 JIT 編譯器。

跟 Java 一樣,我們需要忽略初始的輸出,並跳過 JIT 編譯過程,得到的結果如下:

PyPy 的平均響應速度比 Python 快 5 倍,但仍然比 Go 慢 20 倍。

通過執行這些簡單的數學運算我們可以得出這樣的結論:

Go 的執行速度比 Java 快一些,比解釋運行的 Python 快 2 個數量級。

所以在高負載的關鍵任務上使用Python不是一個好的選擇。

如果小夥伴正面臨這樣的情況,可以考慮使用 Python 編譯器作為短期的應急方案。