究竟哪個版本的Python是最快的?
Python 3 比 Python 2 慢嗎?哪個版本的 Python 3 速度最快?還有哪些措施可以提高速度?究竟哪個版本的 Python 是最快的?當然,“這取決于”多種因素,但它具體取決于什么,我們應(yīng)當如何為自己的應(yīng)用程序找到最快的 Python 版本呢?就這些問題,今天我來試著做一些測試。
使用 Python 性能測試程序
我之前在 speed.python.org 網(wǎng)站上提到過,Python 核心團隊非常關(guān)心性能,這對于比較 CPython 版本的“官方”基準測試非常有用。
但是這個測試依然存在一些問題:
- 測試結(jié)果不易理解
 - 測試不包括 PyPy
 
首先,執(zhí)行指令 pip install performance 來 下載測試程序,然后執(zhí)行以下指令:
pyperformance run --python={chosen_python_runtime} -o my_results.json
該指令將針對 Python 的目標版本多次運行一系列“真實”應(yīng)用的測試程序,并記錄測試結(jié)果的平均值。
在本文中,我主要對以下版本的 Python 進行了測試:
- 2.7.10,
 - 3.4.4,
 - 3.5.4,
 - 3.6.1,
 - 3.7(beta 2)。
 
此外,還測試了 PyPy(5.6)和 PyPy3(5.4.10)。
測試結(jié)果
我已經(jīng)根據(jù)這套測試用例進行了測試,大家可以查看測試結(jié)果。當然,你也可以編寫自己的測試用例并運行自己的測試。
我還編寫了一個簡單的腳本,用來獲取性能數(shù)據(jù)文件列表,并為每個測試結(jié)果制作了非常直觀的圖表。我將這個腳本的代碼放在了 GitHub 上(見文末鏈接)。
在所有圖表中,結(jié)果都以秒為單位,數(shù)值越低說明性能越好。
關(guān)于完整的測試結(jié)果和圖表,可以查看以下鏈接:
https://github.com/tonybaloney/performance_testing/tree/master/png
我認為很重要的測試都包含在其中了。其余的測試與已經(jīng)進行的測試大同小異,已經(jīng)包含在結(jié)論中了。
渲染 HTML 模板
django_html 測試將使用 Django 模板渲染引擎創(chuàng)建一個 150 行×150 列的 HTML 表格。它利用了 Django 引擎的內(nèi)容和模板類。
Python 3.7 的速度 比 Python 2.7 快 1.19 倍,但是除了 Python3.7 之外,其他版本的 Python3 都比 Python 2.7 慢。該結(jié)果與 speed.python.org 網(wǎng)站的測試結(jié)果一致。
PyPy 的測試結(jié)果顯示,其運行速度比任何一個 CPython 的 Python 版本都快得多,而 PyPy3 則會比 PyPy 慢兩倍。需要注意的是,Django 最近決定在 Django 2.0 及更高版本中將放棄對 Python 2 的支持,這意味著 PyPy 將不再與 Django 2 兼容。
啟動時間
該測試主要用來測試 Python 解釋器啟動所花費的時間。如果你打算運行多個進程來打破 Python 的“GIL”約束,那么這將是非常重要的。
此處我先跳過 PyPy,尤其是 PyPy3,我會在文章末尾再進行探討。
從上圖可見,Python 2.7 的啟動時間是最短的。
加密測試:crypto_paes
在加密測試中,你會發(fā)現(xiàn) Python 2 相比 Python 3 的速度明顯快得多。什么原因呢?因為加密需要大量的數(shù)字運算,而 Python 3 廢棄了 32 位整型,取而代之的是長整型。
對于 PyPy 用戶來說,你應(yīng)該會注意到 PyPy3 比 PyPy 慢 5 倍!
算法測試:n-queens
這個算法可能不會讓所有人都舒心,用這個算法來進行測試,可能會勾起一些人當初在算法課上經(jīng)歷的不美好回憶,對此我只能說抱歉了。這個算法的規(guī)則實際上很簡單,就是把 n 個“皇后”放在棋盤上,保證任意兩個“皇后”都不在同一行、同一列或者同一斜線上,使她們攻擊不到彼此。
在 CPython 系列中,Python3.7 的性能再次奪魁。此外,PyPy 和 PyPy3 的測試結(jié)果非常相似。
浮點運算
在浮點運算的測試中,我將人為地通過 math.cos(),math.sin() 和 math.sqrt() 函數(shù)創(chuàng)建繁重的浮點運算應(yīng)用程序,總共創(chuàng)建 10 萬個浮點對象。
從測試結(jié)果可以看出,PyPy 非常適合浮點運算,對于大量的數(shù)據(jù)處理、可預(yù)測的類型和方法以及循環(huán),PyPy 展現(xiàn)出了杰出的性能。由于 Python 3.7 具有新的快速方法調(diào)用操作碼,因此在 CPython 中,它的速度最快。
正則表達式
在正則表達式測試中,“我使用了網(wǎng)絡(luò)上最流行的 50 個網(wǎng)頁,并記錄所有正則表達式操作。每個操作都有一個權(quán)重,它根據(jù)頁面出現(xiàn)的熱門程度以及加載每個頁面時執(zhí)行的次數(shù)計算得來。最后,使用 ROT13 對數(shù)據(jù)中的字母進行編碼,這樣不會影響正則表達式匹配其輸入的方式。”
在這個測試中,我不知道 PyPy 出了什么問題,我很想知道其他人是否得到相同的結(jié)果!
Python 3 比 Python 2 更快嗎?
是的! 在大多數(shù)測試中,Python3 都比 Python2 更快。但有幾個例外情況值得注意,在加密測試中,由于整型數(shù)據(jù)類型的原因,Python 3 的速度比 Python2 慢了 1.35 倍,在啟動時間測試中,Python3 則比 Python2 慢了 1.39 倍。
Python 3 啟動慢的問題將會是 CPython 核心團隊在 3.8 和 3.9 版本中主要解決的問題之一。
除了加密和啟動時間測試之外,在其他的測試項目中,Python 3 的速度比 Python2 大約快 1.2-1.3 倍。改進后的 Python 3.7 升級版將會在今年年底面世。
既然 PyPy 快得多,為什么不是所有人都使用它呢?
PyPy 擁有即時(JIT)編譯器,因此它比 CPython 快。JIT 編譯器具有很大的好處,因為它們在執(zhí)行可預(yù)測的重復(fù)性任務(wù)時非常高效。Python 性能測試的其中一個特點是,你需要多次運行同一段代碼以使其準確無誤,從而減少應(yīng)用程序的錯誤邊界。因此,PyPy 面對這樣的測試性能更優(yōu)。
JIT 編譯器,尤其是 PyPy 的 JIT 編譯器最顯著的缺點是啟動成本高。另一個缺點是許多 C 語言擴展程序缺乏兼容性。因為“Python”(CPython,官方的 PSF Python)是用 C 語言編寫的,PyPi 上的許多第三方擴展利用了這一點。Numpy 就是一個很好的例子,Numpy 的大部分代碼都是用優(yōu)化的 C 代碼編寫的。當你執(zhí)行 pip install numpy 命令時,它會使用本地 C 編譯器為你的 Python 運行時建立一個二進制庫,供 Python 程序使用。
由于 PyPy 是用 Python 編寫的,很多模塊根本無法在 PyPy 中工作,所以你需要經(jīng)常進行檢查。
此外,PyPy 也需要面對與 CPython 相同的挑戰(zhàn):從 Python2 向 Python3 轉(zhuǎn)變。直到最近我仍然發(fā)現(xiàn) PyPy3 不穩(wěn)定,在測試中仍然會出現(xiàn)一些奇怪的結(jié)果。一些其他的軟件包遇到了問題,比如 PyTest,因此它們放棄了對 PyPy3 的支持。
結(jié)論
Python 3.7 是速度最快的“官方”Python 版本,在我測試過的解釋器中,PyPy 則是最快的。
如果 Python2 以后用得越來越少,即使 PyPy3 無法比 PyPy 更快,我也希望它在速度上有所提升。






















 
 
 







 
 
 
 