The speedup provided by Python's new JIT is pretty amazing. A 20% speedup over 3.12! And: no code changes necessary.
Benchmark 1: python3.12 main.py
Time (mean ± σ): 1.213 s ± 0.028 s [User: 1.162 s, System: 0.008 s]
Range (min … max): 1.181 s … 1.281 s 10 runs
Benchmark 2: PYTHON_JIT=0 python3.13 main.py
Time (mean ± σ): 1.124 s ± 0.013 s [User: 1.114 s, System: 0.004 s]
Range (min … max): 1.097 s … 1.137 s 10 runs
Benchmark 3: PYTHON_JIT=1 python3.13 main.py
Time (mean ± σ): 1.007 s ± 0.004 s [User: 0.998 s, System: 0.004 s]
Range (min … max): 1.001 s … 1.013 s 10 runs
Summary
PYTHON_JIT=1 python3.13 main.py ran
1.12 ± 0.01 times faster than PYTHON_JIT=0 python3.13 main.py
1.20 ± 0.03 times faster than python3.12 main.py
How to install Python 3.13 and run the benchmark
brew install llvm
CONFIGURE_OPTS="--enable-experimental-jit=yes-off" pyenv install 3.13.0b1
export PATH="$(pyenv root)/versions/3.13.0b1/bin:$PATH"
hyperfine "python3.12 main.py" "PYTHON_JIT=0 python3.13 main.py" "PYTHON_JIT=1 python3.13 main.py"
The code
import time
import random
def matrix_multiply(a, b):
result = [[0] * len(b[0]) for _ in range(len(a))]
for i in range(len(a)):
for j in range(len(b[0])):
for k in range(len(b)):
result[i][j] += a[i][k] * b[k][j]
return result
def generate_matrix(size):
return [[random.random() for _ in range(size)] for _ in range(size)]
if __name__ == "__main__":
SIZE = 300
random.seed(42)
a = generate_matrix(SIZE)
b = generate_matrix(SIZE)
start_time = time.time()
result = matrix_multiply(a, b)
end_time = time.time()
print(f"Time taken for matrix multiplication: {end_time - start_time} seconds")
Python and system info
$ python3.12 -VV
Python 3.12.2 (main, Apr 22 2024, 17:20:27) [Clang 15.0.0 (clang-1500.3.9.4)]
$ python3.13 -VV
Python 3.13.0b1 (main, May 30 2024, 15:39:04) [Clang 15.0.0 (clang-1500.3.9.4)]
$ neofetch --off --stdout | rg "^(OS|Host|Kernel|[CG]PU|Memory)"
OS: macOS 14.5 23F79 arm64
Host: Mac14,15
Kernel: 23.5.0
CPU: Apple M2
GPU: Apple M2
Memory: 3408MiB / 24576MiB