It has been 2 months since a new version of Python 3.12 has been released. There are many syntax features added making the language more convenient to use. Though what about performance?
Not long ago I created a Mandelbrot set generator in 13 programming languages, Python included. Why not test the most recent version of the runtime? Mandelbrot generation is a CPU-bound benchmark that demonstrates how performant a given language is at executing lots of math computations in nested loops.
Here's the implementation I used, pure Python, no C++ dependencies involved (such as NumPy or Numba).
And here're the results from the MacBook Pro with M1 Pro (ARM CPU):
3.12.0 - ~45 sec
3.11.6 - ~41 sec
3.9.6 - ~67 sec
Dart VM - ~0.47 sec
gcc - ~0.25 sec
Added a few more contenders to the pack. Speaking of the 3.12 version, it is ~10% slower than 3.11, and the results are stably reproducible. Though both 3.12 and 3.11 are significantly faster than 3.9 that comes as standard on macOS.
VMWare, Ubuntu, Intel® Core™ i5-8257U CPU @ 1.40GHz × 2:
3.12.0 - ~54 sec
3.11.6 - ~54 sec
3.10.12 - ~85 sec
3.9.18 - ~85 sec
Dart VM - ~0.62 sec
gcc - ~0.33 sec
For comparison I have added results of Dart implementation (run in VM) and C++ (compiled via gcc
) - we're talking of ~100x difference. This difference reminds of a rule of thumb that you should not do any loops, especially nested ones, with Python, and hand over this kind of workloads to C dependencies. Yet another confirmation of tradeoffs brought by Python - a super convenient glue language which is super slow in computation tasks.
P.S.: I have come across this more holistic comparison of 3.12 to 3.11. It had run pyperformance 1.0.9
on AMD Ryzen 9 7900 and Intel Core i3-1315U, both are x86 CPUs. What is curious is that on average 3.12 was ~10% slower on AMD while ~5% faster on Intel.