Python 3.13がリリースされ、試験導入された機能の一つにJIT(Just-In-Time)コンパイラの導入というのがあったので実際に動かして評価してみたので共有します。
JIT(Just-In-Time)コンパイラは、実行時にコードをコンパイルすることで、パフォーマンスを向上させる技術です。
参考: Python 3.13 Docs
テスト環境
- OS: Windows 11
- CPU: Intel(R) N100
- メモリ: 16GB
検証方法
- Python 3.13.0のソースコードをダウンロードし、LLVM 18.1.8をインストールした環境でビルドしました。
- JITコンパイラを有効にしたPythonと、無効にしたPythonの両方で、以下のベンチマークプログラムを実行しました。
- リスト内包表記
- forループとappend
- 文字列連結 (join)
- 文字列連結 (+)
- 浮動小数点演算
- 辞書操作
- ソート
- 再帰関数
- 各処理にかかった時間を計測し、比較しました。
検証に使用したプログラムはこちらです。
import time
import random
import math
import sys
def list_comprehension_test():
return [i**2 for i in range(500000)]
def list_append_test():
list_append = []
for i in range(500000):
list_append.append(i**2)
return list_append
def string_join_test():
strings = [str(i) for i in range(50000)]
return "".join(strings)
def string_plus_test(): # 非推奨
slow_joined_string = ""
for i in range(50000):
slow_joined_string += str(i)
return slow_joined_string
def float_operation_test():
total = 0
for i in range(500000):
total += math.sqrt(i) * math.sin(i)
return total
def dict_test():
my_dict = {i: i * 2 for i in range(50000)}
for i in range(50000):
value = my_dict[i]
return my_dict
def sort_test():
random_list = [random.randint(0, 100000) for _ in range(50000)]
return sorted(random_list)
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
def recursion_test():
return fibonacci(25) # 再帰の深さを増やす
def measure_execution_time(func, name):
start_time = time.time()
result = func()
end_time = time.time()
elapsed_time = end_time - start_time
print(f"{name}: {elapsed_time:.6f} 秒")
return result
if __name__ == "__main__":
print(f"Python version: {sys.version}")
measure_execution_time(list_comprehension_test, "リスト内包表記")
measure_execution_time(list_append_test, "forループとappend")
measure_execution_time(string_join_test, "文字列連結 (join)")
measure_execution_time(string_plus_test, "文字列連結 (+)")
measure_execution_time(float_operation_test, "浮動小数点演算")
measure_execution_time(dict_test, "辞書操作")
measure_execution_time(sort_test, "ソート")
measure_execution_time(recursion_test, "再帰関数")
前準備(Python 3.13環境のビルド)
リリース版のPython13.0がJITコンパイラありでビルドされているのかがよくわからなかったので、ソースコードからJIT有効・無効版をそれぞれ生成して比較しています。
ソースコードでビルドする方法を簡単に紹介しておきます。
Step1 LLVMのインストール
以下から、LLVM-18.1.8-win64.exeをダウンロードし、インストールします。
この時に、環境変数にLLVMを通しておいてください。
また、LLVMはビルドの時にバージョンを確認されていますので、最新版ではなく、Ver18のものをインストールしてください。
※最新でやろうとしてビルドが通らなくて、少しハマりました。。
Step2 ソースコードのダウンロード
以下からPython13.0をダウンロードして任意のフォルダに格納します。
私は、XZ compressed source tarballをダウンロードしました。
Step3 ビルド
PowerShellを開いて以下のように実行します。
※XXXXは任意のフォルダという意味です。
JIT有効版の生成
cd XXXX\Python-3.13.0
.\PCbuild\build.bat --experimental-jit
JIT無効版の生成
cd XXXX\Python-3.13.0
.\PCbuild\build.bat --experimental-jit-off
実行
ビルドが完了していれば、以下のフォルダに生成物が格納されます。
XXX\Python-3.13.0\PCbuild\amd64
実行する場合は、このamd64の下の、「python.exe」を実行してください。
検証結果比較
比較検証として、Python 3.11.9、Python 3.13.0 (リリース版)、Python 3.13.0 (JIT無効)、Python 3.13.0 (JIT有効)の4つの環境でベンチマークをとってみました。
その実行した結果は以下のようになりました。
ベンチマーク | Python 3.11.9 | Python 3.13.0 (リリース版) | Python 3.13.0 (JIT無効) | Python 3.13.0 (JIT有効) |
リスト内包表記 | 0.089201 秒 | 0.043618 秒 | 0.047074 秒 | 0.044584 秒 |
forループとappend | 0.149219 秒 | 0.045507 秒 | 0.050257 秒 | 0.043370 秒 |
文字列連結 (join) | 0.016875 秒 | 0.005983 秒 | 0.007592 秒 | 0.006132 秒 |
文字列連結 (+) | 0.275465 秒 | 0.009098 秒 | 0.009865 秒 | 0.011287 秒 |
浮動小数点演算 | 0.263088 秒 | 0.106901 秒 | 0.122194 秒 | 0.095306 秒 |
辞書操作 | 0.013840 秒 | 0.009813 秒 | 0.008395 秒 | 0.008476 秒 |
ソート | 0.161808 秒 | 0.038749 秒 | 0.038990 秒 | 0.030762 秒 |
再帰関数 | 0.151935 秒 | 0.015169 秒 | 0.017644 秒 | 0.013690 秒 |
考察
JITコンパイラを有効にしたPython 3.13.0では、若干ですが、ベンチマークで処理速度が向上している傾向が見られました。特に、浮動小数点演算やソート、再帰関数など、計算量の多い処理がその傾向にあるようです。
また検証の結果としては、リリース版のPython 3.13.0でもJITコンパイラが有効になっているものと思われます。
個人的に一番興味深かったのは、Python 3.11->Python 3.13で劇的に性能が上がっていることです。
この比較結果を見ると、今まで安定性や依存関係等を考えてあまりアプデートせずに古いままで使っていましたが、Pythonはできるだけ最新版を使うべきなんだなと考えさせられました。
まとめ
Python 3.13のJITコンパイラは、パフォーマンス向上に貢献する可能性を秘めています。特に、計算量の多い処理では、その効果がより顕著に現れるでしょう。今後のPython開発において、どんどん進化していくことで、よりパフォーマンスは向上していくでしょうから、Pythonはまだまだ現役なんだと感じれました。
この記事が、あなたの役に立てば幸いです!
Pythonのバージョン違いによるパフォーマンスも比較してみたので、気になる方はこちら
コメント