> For the complete documentation index, see [llms.txt](https://docs.xiwind-corp.com/tech/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.xiwind-corp.com/tech/python/pypyjit-bian-yi-qi.md).

# 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](https://en.wikipedia.org/wiki/Dead-code_elimination) (刪除不影響最終結果的部分程式碼)，執行 [Loop unrolling](https://en.wikipedia.org/wiki/Loop_unrolling) (犧牲程式碼的大小，從而減少循環控制的 overhead)。

## 安裝 PyPy – Conda

***

{% code title="SHELL" %}

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

{% endcode %}

### 安裝 Library

***

{% code title="SHELL" %}

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

{% endcode %}

## 測試 PyPy

***

{% hint style="info" %}
`.py` 檔案路徑必須是英文，否則會 `[Errno 2] No such file or directory`。
{% endhint %}

{% code title="PYTHON" %}

```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")


```

{% endcode %}

**執行結果：**

```
# 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 鏡像](https://github.com/mozillazg/pypy)

[PyPy GitLab](https://foss.heptapod.net/pypy/pypy)

[下載並安裝 | PyPy](https://www.pypy.org/download.html)

[下載並安裝 PyPy — PyPy 文檔](https://doc.pypy.org/en/latest/install.html)

[ubuntu安裝PyPy以及pypy在anaconda虛擬環境中的使用\_ubuntu pypy\_遊子身上汗的博客-CSDN博客](https://blog.csdn.net/weixin_45827423/article/details/122400313)

[pypy安裝pip以及利用pip安裝其它庫使用教程\_pypy pip\_P0級推薦演算法工程師的博客-CSDN博客](https://blog.csdn.net/SunStrongInChina/article/details/111238778)

[用 PyPy 讓你的 Python 代碼運行得更快！ - 知乎](https://zhuanlan.zhihu.com/p/293154940)

[下載並安裝 PyPy — PyPy 文檔](https://doc.pypy.org/en/latest/install.html)

[PyPy：以最少的努力實現更快的 Python – 真正的 Python](https://realpython.com/pypy-faster-python/)
