PEP 744 – JIT Compilation
peps.python.org
peps.python.org
At first it will not provide a large boost, but it will set the foundations for larger gains in subsequent releases. They link a list of some proposed improvements already underway, with quantitative estimates, at https://github.com/python/cpython/issues/115802 The TL;DR is:
> Stop using the "large" code model. (...) Benchmarking runs suggest that this change will give us a ~1-3% performance improvement, depending on platform.
> Remove zero-length jumps when tail-calling between templates. (...) Benchmarking suggests that this change will give us an additional ~1-3% performance improvement.
> Use LLVM's ghccc/preserve_none calling convention when tail-calling between templates. (...) Benchmarking suggests that this change will give us an additional ~0-6% performance improvement (no wins on aarch64, moderate wins on x86_64, and big wins on i686).
> Split hot and cold parts of the templates. (...) Early experiments suggest a ~1-2% performance improvement with this approach.
> Cache top-of-stack values in registers when tail-calling between templates. (...) No idea what this will win us, but it should be good given the amount of memory traffic that's being reduced to and from interpreter frames.
So, beyond the expected base boost of 5%, there's 5 near term improvements planned, 4 of which with estimates given. I compounded the estimates to see how far we should expect them to take performance together:
Python 3.11.2 (main, Mar 13 2023, 12:18:29) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license()" for more information.
from itertools import accumulate, chain
from operator import mul
from statistics import mean
base_boost = 1.05
estimated_bounds = [(1.01, 1.03),
(1.01, 1.03),
(1.00, 1.06),
(1.01, 1.02)]
worst_mean_best_cases = [map(min, estimated_bounds),
map(mean, estimated_bounds),
map(max, estimated_bounds)]
f = lambda iterable: list(round(e, 3) for e in accumulate(iterable, mul, initial=base_boost))
for line in chain([('worst', 'mean', 'best')], zip(*map(f, worst_mean_best_cases))):
print(*line)
worst mean best
1.05 1.05 1.05
1.06 1.071 1.082
1.071 1.092 1.114
1.071 1.125 1.181
1.082 1.142 1.204
So, if all short-term planned improvements are implemented, I believe we should expect a 8% performance boost in worst case, 20% in best case, with average around 14%, not counting the effects of caching top-of-stack values in registers when tail-calling between templates, for which no bound estimates were given.