This article describes the performance testing results of Python 3.10 compared to Python 3.9. A total of 88 various benchmark tests were conducted on computers with the AMD Ryzen 7000 series and the 13th-generation of Intel Core processors for desktops, laptops or mini PCs.
All tests were run on Windows 11 computers using the pyperformance 1.0.9 library in Python 3.9.13 and Python 3.10.11 (both 64-bit versions).
AMD Ryzen 7000 Series Desktop Processor
The first part of testing involved a desktop computer with an AMD Ryzen 9 7900 processor, RAM DDR5, and an M.2 PCIe Gen4 NVMe drive. The table below shows the results of 88 tests performed using Python 3.9 (as a reference) and Python 3.10 on this device.
Benchmark | Python 3.9 | Python 3.10 |
---|---|---|
2to3 | 217 ms | 216 ms (not significant) |
async_generators | 221 ms | 230 ms (1.04x slower) |
async_tree_cpu_io_mixed | 682 ms | 685 ms (not significant) |
async_tree_io | 1.33 sec | 1.32 sec (not significant) |
async_tree_memoization | 559 ms | 560 ms (not significant) |
async_tree_none | 479 ms | 471 ms (not significant) |
asyncio_tcp | 619 ms | 686 ms (1.11x slower) |
asyncio_tcp_ssl | 1.76 sec | 2.04 sec (1.16x slower) |
bench_mp_pool | 56.7 ms | 55.4 ms (1.02x faster) |
bench_thread_pool | 706 us | 725 us (1.03x slower) |
chameleon | 6.03 ms | 5.89 ms (1.02x faster) |
chaos | 57.6 ms | 57.1 ms (1.01x faster) |
comprehensions | 14.5 us | 14.6 us (not significant) |
coroutines | 21.4 ms | 17.3 ms (1.24x faster) |
coverage | 25.5 ms | 33.5 ms (1.31x slower) |
create_gc_cycles | 635 us | 637 us (1.00x slower) |
crypto_pyaes | 61.8 ms | 62.7 ms (1.01x slower) |
dask | 269 ms | 263 ms (1.02x faster) |
deepcopy | 245 us | 253 us (1.03x slower) |
deepcopy_memo | 28.3 us | 28.9 us (1.02x slower) |
deepcopy_reduce | 2.19 us | 2.20 us (not significant) |
deltablue | 4.00 ms | 4.27 ms (1.07x slower) |
django_template | 28.4 ms | 28.2 ms (1.01x faster) |
docutils | 1.57 sec | 1.63 sec (1.04x slower) |
fannkuch | 263 ms | 256 ms (not significant) |
float | 66.6 ms | 66.7 ms (not significant) |
gc_traversal | 1.20 ms | 1.20 ms (not significant) |
generators | 32.8 ms | 41.8 ms (1.27x slower) |
genshi_text | 19.1 ms | 18.7 ms (1.02x faster) |
genshi_xml | 140 ms | 132 ms (not significant) |
hexiom | 5.26 ms | 5.46 ms (1.04x slower) |
html5lib | 41.6 ms | 39.3 ms (1.06x faster) |
json_dumps | 8.28 ms | 8.09 ms (1.02x faster) |
json_loads | 14.0 us | 13.3 us (1.05x faster) |
logging_format | 6.22 us | 6.74 us (1.08x slower) |
logging_silent | 104 ns | 102 ns (not significant) |
logging_simple | 5.78 us | 6.36 us (1.10x slower) |
mako | 9.41 ms | 9.04 ms (1.04x faster) |
mdp | 1.77 sec | 1.68 sec (1.05x faster) |
meteor_contest | 63.7 ms | 65.9 ms (1.04x slower) |
nbody | 80.7 ms | 81.8 ms (1.01x slower) |
nqueens | 57.7 ms | 61.3 ms (1.06x slower) |
pathlib | 80.5 ms | 81.3 ms (1.01x slower) |
pickle | 6.98 us | 6.86 us (1.02x faster) |
pickle_dict | 17.9 us | 18.5 us (1.03x slower) |
pickle_list | 2.49 us | 2.58 us (1.04x slower) |
pickle_pure_python | 250 us | 258 us (1.03x slower) |
pidigits | 139 ms | 136 ms (1.02x faster) |
pprint_pformat | 900 ms | 1.17 sec (1.30x slower) |
pyflate | 394 ms | 387 ms (1.02x faster) |
python_startup | 17.7 ms | 17.4 ms (1.01x faster) |
python_startup_no_site | 13.2 ms | 13.2 ms (not significant) |
raytrace | 267 ms | 275 ms (1.03x slower) |
regex_compile | 86.8 ms | 89.5 ms (1.03x slower) |
regex_dna | 106 ms | 111 ms (1.04x slower) |
regex_effbot | 1.81 ms | 1.78 ms (1.01x faster) |
regex_v8 | 14.9 ms | 15.0 ms (1.01x slower) |
richards | 38.0 ms | 41.7 ms (1.10x slower) |
richards_super | 48.5 ms | 50.9 ms (1.05x slower) |
scimark_fft | 205 ms | 223 ms (1.09x slower) |
scimark_lu | 85.4 ms | 94.3 ms (1.10x slower) |
scimark_monte_carlo | 57.9 ms | 58.1 ms (not significant) |
scimark_sor | 105 ms | 105 ms (not significant) |
scimark_sparse_mat_mult | 3.04 ms | 3.47 ms (1.14x slower) |
spectral_norm | 79.7 ms | 82.1 ms (1.03x slower) |
sqlalchemy_declarative | 72.4 ms | 78.0 ms (1.08x slower) |
sqlalchemy_imperative | 8.55 ms | 8.51 ms (1.01x faster) |
sqlglot_normalize | 181 ms | 198 ms (1.10x slower) |
sqlglot_optimize | 34.6 ms | 37.1 ms (1.07x slower) |
sqlglot_parse | 1.20 ms | 1.12 ms (1.07x faster) |
sqlglot_transpile | 1.36 ms | 1.33 ms (1.03x faster) |
sqlite_synth | 1.68 us | 1.54 us (1.09x faster) |
sympy_expand | 261 ms | 265 ms (1.02x slower) |
sympy_integrate | 12.8 ms | 12.7 ms (1.01x faster) |
sympy_str | 159 ms | 162 ms (1.02x slower) |
sympy_sum | 87.4 ms | 91.4 ms (1.05x slower) |
telco | 3.89 ms | 3.80 ms (1.02x faster) |
tomli_loads | 1.57 sec | 1.69 sec (1.07x slower) |
tornado_http | 101 ms | 98.2 ms (1.03x faster) |
typing_runtime_protocols | 301 us | 314 us (1.04x slower) |
unpack_sequence | 35.0 ns | 39.3 ns (1.12x slower) |
unpickle | 7.90 us | 8.59 us (1.09x slower) |
unpickle_list | 2.87 us | 2.87 us (not significant) |
unpickle_pure_python | 171 us | 176 us (1.03x slower) |
xml_etree_generate | 53.7 ms | 55.2 ms (1.03x slower) |
xml_etree_iterparse | 55.4 ms | 57.6 ms (1.04x slower) |
xml_etree_parse | 84.1 ms | 83.4 ms (1.01x faster) |
xml_etree_process | 42.9 ms | 44.4 ms (1.04x slower) |
Result (geometric mean) | 1.02x slower |
The result shows that Python 3.10 has the best performance results over Python 3.9 in the following tests: coroutines (1.24x faster), sqlite_synth (1.09x faster), sqlglot_parse (1.07x faster). However, you may notice a drop in performance in some tests, especially in coverage (1.31x slower), pprint_pformat (1.30x slower), generators (1.27x slower).
Additionally, you can examine the performance differences between Python 3.10 and Python 3.9 based on benchmarks belonging to specific groups. The table below shows the geometric mean for benchmarks from separate groups for Python 3.10 compared to Python 3.9.
Group of benchmarks | Python 3.10 to Python 3.9 |
---|---|
apps | 1.01x faster |
math | 1.00x faster |
regex | 1.02x slower |
serialize | 1.02x slower |
startup | 1.01x faster |
template | 1.02x faster |
13th Gen Intel Core Mobile Processor
The second part of testing involved a mini PC with an Intel Core i3-1315U Processor (which is also used in laptops), RAM DDR4, and an M.2 PCIe Gen4 NVMe drive. The table below shows the results of 88 tests performed using Python 3.9 (as a reference) and Python 3.10 on this device.
Benchmark | Python 3.9 | Python 3.10 |
---|---|---|
2to3 | 281 ms | 282 ms (not significant) |
async_generators | 249 ms | 254 ms (1.02x slower) |
async_tree_cpu_io_mixed | 708 ms | 716 ms (1.01x slower) |
async_tree_io | 1.17 sec | 1.16 sec (1.01x faster) |
async_tree_memoization | 583 ms | 593 ms (1.02x slower) |
async_tree_none | 479 ms | 486 ms (not significant) |
asyncio_tcp | 912 ms | 981 ms (1.08x slower) |
asyncio_tcp_ssl | 2.24 sec | 2.43 sec (1.08x slower) |
bench_mp_pool | 92.4 ms | 89.5 ms (1.03x faster) |
bench_thread_pool | 1.20 ms | 1.24 ms (not significant) |
chameleon | 6.93 ms | 6.47 ms (1.07x faster) |
chaos | 69.2 ms | 68.8 ms (not significant) |
comprehensions | 16.3 us | 18.4 us (1.13x slower) |
coroutines | 25.4 ms | 18.0 ms (1.42x faster) |
coverage | 25.2 ms | 33.0 ms (1.31x slower) |
create_gc_cycles | 883 us | 888 us (not significant) |
crypto_pyaes | 70.5 ms | 70.3 ms (not significant) |
dask | 436 ms | 431 ms (1.01x faster) |
deepcopy | 288 us | 293 us (1.02x slower) |
deepcopy_memo | 31.2 us | 32.0 us (1.03x slower) |
deepcopy_reduce | 2.52 us | 2.47 us (1.02x faster) |
deltablue | 4.50 ms | 4.71 ms (1.05x slower) |
django_template | 34.6 ms | 33.3 ms (1.04x faster) |
docutils | 2.08 sec | 2.19 sec (1.05x slower) |
fannkuch | 289 ms | 306 ms (1.06x slower) |
float | 73.1 ms | 70.0 ms (1.04x faster) |
gc_traversal | 1.69 ms | 1.69 ms (not significant) |
generators | 34.4 ms | 36.0 ms (1.05x slower) |
genshi_text | 21.1 ms | 21.6 ms (1.02x slower) |
genshi_xml | 157 ms | 153 ms (1.03x slower) |
hexiom | 5.86 ms | 6.22 ms (1.06x slower) |
html5lib | 56.1 ms | 56.0 ms (not significant) |
json_dumps | 8.96 ms | 9.76 ms (1.09x slower) |
json_loads | 16.5 us | 16.0 us (1.03x faster) |
logging_format | 7.50 us | 8.15 us (1.09x slower) |
logging_silent | 110 ns | 106 ns (1.04x faster) |
logging_simple | 6.97 us | 7.60 us (1.09x slower) |
mako | 10.5 ms | 9.78 ms (1.07x faster) |
mdp | 1.99 sec | 1.96 sec (1.02x faster) |
meteor_contest | 81.9 ms | 83.7 ms (1.02x slower) |
nbody | 81.5 ms | 80.5 ms (not significant) |
nqueens | 69.8 ms | 75.9 ms (1.09x slower) |
pathlib | 74.6 ms | 77.5 ms (1.04x slower) |
pickle | 7.89 us | 7.85 us (not significant) |
pickle_dict | 20.0 us | 20.9 us (1.04x slower) |
pickle_list | 3.01 us | 3.11 us (1.03x slower) |
pickle_pure_python | 292 us | 302 us (1.04x slower) |
pidigits | 170 ms | 167 ms (1.02x faster) |
pprint_pformat | 1.05 sec | 1.39 sec (1.33x slower) |
pyflate | 471 ms | 461 ms (1.02x faster) |
python_startup | 25.1 ms | 25.0 ms (not significant) |
python_startup_no_site | 19.8 ms | 19.4 ms (1.02x faster) |
raytrace | 301 ms | 320 ms (1.06x slower) |
regex_compile | 112 ms | 118 ms (1.05x slower) |
regex_dna | 147 ms | 148 ms (not significant) |
regex_effbot | 1.78 ms | 1.88 ms (1.06x slower) |
regex_v8 | 16.5 ms | 17.0 ms (1.03x slower) |
richards | 41.1 ms | 46.6 ms (1.13x slower) |
richards_super | 51.7 ms | 58.5 ms (1.13x slower) |
scimark_fft | 211 ms | 214 ms (1.01x slower) |
scimark_lu | 87.0 ms | 93.7 ms (1.08x slower) |
scimark_monte_carlo | 65.7 ms | 64.1 ms (1.03x faster) |
scimark_sor | 111 ms | 114 ms (1.03x slower) |
scimark_sparse_mat_mult | 2.95 ms | 2.97 ms (not significant) |
spectral_norm | 86.0 ms | 84.8 ms (1.02x faster) |
sqlalchemy_declarative | 115 ms | 125 ms (1.09x slower) |
sqlalchemy_imperative | 13.3 ms | 13.1 ms (1.02x faster) |
sqlglot_normalize | 207 ms | 234 ms (1.13x slower) |
sqlglot_optimize | 41.0 ms | 44.8 ms (1.09x slower) |
sqlglot_parse | 1.38 ms | 1.40 ms (1.01x slower) |
sqlglot_transpile | 1.62 ms | 1.67 ms (1.03x slower) |
sqlite_synth | 2.26 us | 2.16 us (1.05x faster) |
sympy_expand | 352 ms | 367 ms (1.04x slower) |
sympy_integrate | 16.7 ms | 17.4 ms (1.04x slower) |
sympy_str | 212 ms | 223 ms (1.05x slower) |
sympy_sum | 115 ms | 124 ms (1.08x slower) |
telco | 4.38 ms | 4.42 ms (1.01x slower) |
tomli_loads | 1.75 sec | 1.89 sec (1.08x slower) |
tornado_http | 142 ms | 140 ms (1.02x faster) |
typing_runtime_protocols | 361 us | 378 us (1.05x slower) |
unpack_sequence | 40.9 ns | 44.9 ns (1.10x slower) |
unpickle | 9.05 us | 9.21 us (not significant) |
unpickle_list | 2.99 us | 3.16 us (1.06x slower) |
unpickle_pure_python | 199 us | 209 us (1.05x slower) |
xml_etree_generate | 59.5 ms | 61.8 ms (1.04x slower) |
xml_etree_iterparse | 69.7 ms | 74.4 ms (1.07x slower) |
xml_etree_parse | 113 ms | 114 ms (not significant) |
xml_etree_process | 54.6 ms | 49.5 ms (1.10x faster) |
Result (geometric mean) | 1.03x slower |
The result shows that Python 3.10 has the best performance results over Python 3.9 in the following tests: coroutines (1.42x faster), xml_etree_process (1.10x faster), chameleon (1.07x faster). However, you may notice a drop in performance in some tests, especially in pprint_pformat (1.33x slower), coverage (1.31x slower), comprehensions (1.13x slower).
Additionally, you can examine the performance differences between Python 3.10 and Python 3.9 based on benchmarks belonging to specific groups. The table below shows the geometric mean for benchmarks from separate groups for Python 3.10 compared to Python 3.9.
Group of benchmarks | Python 3.10 to Python 3.9 |
---|---|
apps | 1.01x faster |
asyncio | 1.01x slower |
math | 1.03x faster |
regex | 1.04x slower |
serialize | 1.03x slower |
startup | 1.01x faster |
template | 1.01x faster |