# 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/)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.xiwind-corp.com/tech/python/pypyjit-bian-yi-qi.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
