Page cover

PyPy 【JIT 編譯器】

PyPy


PyPy 是一種 Python 解釋器和 JIT 編譯器 (Just-In-Time compiler),目的在於提高 Python 程式碼的執行速度。 PyPy 的主要目標是符合 Python 語言規範,同時速度更快、使用更少的 memory 並在實現中提供更大的靈活性。 PyPy 是用 RPython 編寫的,RPython 是 Python 的一個受限子集,適合靜態分析,因此可以進行提前編譯。

PyPy 的工作原理是使用 JIT 編譯器在執行時將 Python 程式碼編譯為機器碼,類似於 Numba。 然而主要的區別在於優化的方式和目標。PyPy 目的在成為標準 Python 解釋器 (CPython) 的直接替代品。 它會最佳化您的整個 Python 程序,並且不需要修改 Python 程式碼即可從 PyPy 當中受益。

它透過在程序執行時分析程序、識別 "hot spots" (花費最多時間的程式碼部分) 並將這些部分即時編譯為機器碼來實現此目的。 PyPy 使用 meta-tracing,這是一種從解釋器自動生成 JIT 編譯器的技術,使其能夠有效地執行 Python 等動態類型語言。

另一方面,Numba 並不是一個完整的 Python 解釋器替代品,而是一個可讓您優化單個函數的 Python library。 使用 Numba,您可以使用特殊的 decorators 來指定您想要優化的函數。 Numba 特別擅長優化數值計算,例如:涉及 NumPy 數組的數值計算,並且可以使用 SIMD 指令或 GPU 指令進行計算。

PyPy 和 Numba 都有各自的用法:

  • 對於不嚴重依賴擴充 modules 或計算 hot spots 難以隔離到函數中的純 Python 程式碼來說,PyPy 是一個絕佳的選擇。 對於大量使用擴展 modules 的 Python 程序 (例如:科學 Python stack),PyPy 無法有效地優化它們。(因為這些 modules 通常是為了 CPython API 編寫的)

  • Numba 在數值和科學 Python 領域大放異彩,尤其是當計算的瓶頸可以隔離到函數時。 它提供了一種用高級語言編寫高性能程式碼的方法,甚至可以編譯程式碼以在 GPU 上執行。

JIT 編譯器


JIT 編譯器 (Just-In-Time compiler) 是一種編譯器,它在程序執行期間 (而不是在執行之前) 將程式碼轉換為機器可讀的指令 (傳統的提前編譯器就是這種情況)。 JIT 編譯器的目標是在不影響編程語言的情況下,提高執行速度。 這對於像動態語言 (例如:Python, Java, JavaScript..) 非常有益。

JIT 編譯器的優點是它可以根據程序的當前狀態做出"現場"決策——編譯器可以看到程序如何運行並相應地進行優化。例如:inlining functions (用被調用函數的主體替換函數調用站點)、消除 Dead code (刪除不影響最終結果的部分程式碼),執行 Loop unrolling (犧牲程式碼的大小,從而減少循環控制的 overhead)。

安裝 PyPy – Conda


SHELL
conda create -n pypy_latest pypy -c https://conda.anaconda.org/conda-forge

安裝 Library


SHELL
pypy -m ensurepip
pypy -mpip install -U pip wheel   # to upgrade to the latest versions
pypy -mpip install numpy          # for example

測試 PyPy


.py 檔案路徑必須是英文,否則會 [Errno 2] No such file or directory

PYTHON
import time

def is_prime(n, m): 
    total = 0
    for i in range(1, n):
        for j in range(1, m):
            total += i + j
    return total

start_time = time.time()
print(f"The result is {is_prime(10000, 1000)}")
end_time = time.time()

print(f"Executed in {end_time-start_time:.3f} s")

執行結果:

# is_prime(10000, 1000)
# pypy 3.9
Executed in 0.009 s

# python 3.9
Executed in 0.537 s
# =========================================================
# is_prime(10000, 10000)
# pypy 3.9
Executed in 0.059 s

# python 3.9
Executed in 4.590 s
# =========================================================
# is_prime(10000, 100000)
# pypy 3.9
Executed in 0.557 s

# python 3.9
Executed in 45.963 s

參考資料


PyPy 的非官方 GitHub 鏡像

PyPy GitLab

下載並安裝 | PyPy

下載並安裝 PyPy — PyPy 文檔

ubuntu安裝PyPy以及pypy在anaconda虛擬環境中的使用_ubuntu pypy_遊子身上汗的博客-CSDN博客

pypy安裝pip以及利用pip安裝其它庫使用教程_pypy pip_P0級推薦演算法工程師的博客-CSDN博客

用 PyPy 讓你的 Python 代碼運行得更快! - 知乎

下載並安裝 PyPy — PyPy 文檔

PyPy:以最少的努力實現更快的 Python – 真正的 Python

Last updated

Was this helpful?