Python 3.8 kontra Python 3.9 – test wydajności

Ten artykuł opisuje wyniki testów wydajnościowych dla Pythona 3.9 w porównaniu do poprzedniej wersji tego języka programowania, którym jest Python 3.8. W sumie zostało przeprowadzono 89 różnych testów porównawczych na komputerach z procesorem serii AMD Ryzen 7000 oraz procesorem Intel Core 13. generacji. Jeden z nich używany jest w komputerach stacjonarnych, drugi – w laptopach lub komputerach mini PC.

Wszystkie testy zostały przeprowadzone na komputerach z systemem Windows 11 przy użyciu biblioteki pyperformance 1.0.9 w Pythonie 3.8.10 oraz Pythonie 3.9.13 (obie wersje 64-bitowe).

Procesor AMD Ryzen z serii 7000 do komputerów stacjonarnych

Pierwsza część testów obejmowała komputer stacjonarny z procesorem AMD Ryzen 9 7900, pamięcią RAM DDR5 i dyskiem M.2 PCIe Gen4 NVMe. Poniższa tabela przedstawia wyniki 89 testów przeprowadzonych przy użyciu Pythona 3.8 (jako punktu odniesienia) i Pythona 3.9 na tym urządzeniu.

Nazwa testu Python 3.8 Python 3.9
2to3 216 ms 217 ms (nieistotne)
async_generators 231 ms 221 ms (1.04x szybciej)
async_tree_cpu_io_mixed 683 ms 682 ms (nieistotne)
async_tree_io 1.35 sec 1.33 sec (1.01x szybciej)
async_tree_memoization 552 ms 559 ms (nieistotne)
async_tree_none 456 ms 479 ms (1.05x wolniej)
asyncio_tcp 650 ms 619 ms (1.05x szybciej)
asyncio_tcp_ssl 1.84 sec 1.76 sec (1.04x szybciej)
bench_mp_pool 55.1 ms 56.7 ms (1.03x wolniej)
bench_thread_pool 727 us 706 us (1.03x szybciej)
chameleon 7.19 ms 6.03 ms (1.19x szybciej)
chaos 60.9 ms 57.6 ms (1.06x szybciej)
comprehensions 14.3 us 14.5 us (nieistotne)
coroutines 21.9 ms 21.4 ms (1.02x szybciej)
coverage 25.4 ms 25.5 ms (nieistotne)
create_gc_cycles 602 us 635 us (1.05x wolniej)
crypto_pyaes 65.0 ms 61.8 ms (1.05x szybciej)
dask 265 ms 269 ms (1.02x wolniej)
deepcopy 252 us 245 us (1.03x szybciej)
deepcopy_memo 29.0 us 28.3 us (1.02x szybciej)
deepcopy_reduce 2.24 us 2.19 us (1.02x szybciej)
deltablue 4.06 ms 4.00 ms (1.01x szybciej)
django_template 29.4 ms 28.4 ms (1.03x szybciej)
docutils 1.54 sec 1.57 sec (1.02x wolniej)
dulwich_log 43.9 ms 42.7 ms (1.03x szybciej)
fannkuch 264 ms 263 ms (nieistotne)
float 67.4 ms 66.6 ms (1.01x szybciej)
gc_traversal 1.43 ms 1.20 ms (1.19x szybciej)
generators 33.5 ms 32.8 ms (1.02x szybciej)
genshi_text 18.7 ms 19.1 ms (1.02x wolniej)
genshi_xml 139 ms 140 ms (1.08x szybciej)
hexiom 5.57 ms 5.26 ms (1.06x szybciej)
html5lib 41.4 ms 41.6 ms (nieistotne)
json_dumps 8.16 ms 8.28 ms (1.02x wolniej)
json_loads 15.8 us 14.0 us (1.13x szybciej)
logging_format 6.29 us 6.22 us (1.01x szybciej)
logging_silent 104 ns 104 ns (nieistotne)
logging_simple 5.92 us 5.78 us (1.02x szybciej)
mako 9.58 ms 9.41 ms (1.02x szybciej)
mdp 1.64 sec 1.77 sec (1.08x wolniej)
meteor_contest 64.7 ms 63.7 ms (1.02x szybciej)
nbody 76.8 ms 80.7 ms (1.05x wolniej)
nqueens 60.8 ms 57.7 ms (1.05x szybciej)
pathlib 81.5 ms 80.5 ms (1.01x szybciej)
pickle 6.68 us 6.98 us (1.04x wolniej)
pickle_dict 17.9 us 17.9 us (nieistotne)
pickle_list 2.57 us 2.49 us (1.03x szybciej)
pickle_pure_python 255 us 250 us (1.02x szybciej)
pidigits 136 ms 139 ms (1.02x wolniej)
pprint_pformat 902 ms 900 ms (nieistotne)
pyflate 394 ms 394 ms (nieistotne)
python_startup 17.8 ms 17.7 ms (1.01x szybciej)
python_startup_no_site 13.4 ms 13.2 ms (1.02x szybciej)
raytrace 272 ms 267 ms (1.02x szybciej)
regex_compile 88.5 ms 86.8 ms (1.02x szybciej)
regex_dna 116 ms 106 ms (1.09x szybciej)
regex_effbot 1.90 ms 1.81 ms (1.05x szybciej)
regex_v8 15.1 ms 14.9 ms (1.01x szybciej)
richards 38.3 ms 38.0 ms (1.01x szybciej)
richards_super 47.1 ms 48.5 ms (1.03x wolniej)
scimark_fft 212 ms 205 ms (1.03x szybciej)
scimark_lu 86.3 ms 85.4 ms (1.01x szybciej)
scimark_monte_carlo 58.1 ms 57.9 ms (nieistotne)
scimark_sor 104 ms 105 ms (nieistotne)
scimark_sparse_mat_mult 3.08 ms 3.04 ms (1.01x szybciej)
spectral_norm 81.9 ms 79.7 ms (1.03x szybciej)
sqlalchemy_declarative 72.5 ms 72.4 ms (nieistotne)
sqlalchemy_imperative 8.39 ms 8.55 ms (1.02x wolniej)
sqlglot_normalize 185 ms 181 ms (1.02x szybciej)
sqlglot_optimize 35.0 ms 34.6 ms (1.01x szybciej)
sqlglot_parse 1.17 ms 1.20 ms (1.03x wolniej)
sqlglot_transpile 1.36 ms 1.36 ms (nieistotne)
sqlite_synth 1.83 us 1.68 us (1.09x szybciej)
sympy_expand 255 ms 261 ms (1.03x wolniej)
sympy_integrate 12.3 ms 12.8 ms (1.04x wolniej)
sympy_str 155 ms 159 ms (1.02x wolniej)
sympy_sum 86.3 ms 87.4 ms (1.01x wolniej)
telco 3.62 ms 3.89 ms (1.07x wolniej)
tomli_loads 1.65 sec 1.57 sec (1.05x szybciej)
tornado_http 101 ms 101 ms (nieistotne)
typing_runtime_protocols 316 us 301 us (1.05x szybciej)
unpack_sequence 34.3 ns 35.0 ns (1.02x wolniej)
unpickle 9.60 us 7.90 us (1.21x szybciej)
unpickle_list 2.70 us 2.87 us (1.06x wolniej)
unpickle_pure_python 175 us 171 us (1.02x szybciej)
xml_etree_generate 57.9 ms 53.7 ms (1.08x szybciej)
xml_etree_iterparse 55.3 ms 55.4 ms (nieistotne)
xml_etree_parse 85.7 ms 84.1 ms (1.02x szybciej)
xml_etree_process 44.7 ms 42.9 ms (1.04x szybciej)
Wynik (średnia geometryczna) 1.02x szybciej

Przeprowadzona analiza wskazuje na to, że Python 3.9 ma najlepsze wyniki wydajnościowe w porównaniu do Pythona 3.8 w następujących testach: unpickle (1.21x szybciej), chameleon (1.19x szybciej), gc_traversal (1.19x szybciej). Można jednak zauważyć spadek wydajności w niektórych testach, szczególnie w genshi_xml (1.08x szybciej), mdp (1.08x wolniej), telco (1.07x wolniej).

Dodatkowo można sprawdzić różnice w wydajności pomiędzy Pythonem 3.9 i Pythonem 3.8 w oparciu o testy należące do określonych grup. Poniższa tabela przedstawia średnią geometryczną dla testów porównawczych w ramach poszczególnych grup dla Pythona 3.9 w porównaniu z Pythonem 3.8.

Grupa testów Python 3.9 w porównaniu do Pythona 3.8
apps 1.03x szybciej
asyncio 1.01x wolniej
math 1.02x wolniej
regex 1.04x szybciej
serialize 1.03x szybciej
startup 1.01x szybciej
template 1.03x szybciej

Procesor Intel Core 13. generacji dla urządzeń mobilnych

Druga część testów obejmowała komputer mini PC z procesorem Intel Core i3-1315U (który jest również używany w laptopach), pamięcią RAM DDR4 i dyskiem M.2 PCIe Gen4 NVMe. Poniższa tabela przedstawia wyniki 89 testów przeprowadzonych przy użyciu Pythona 3.8 (jako punktu odniesienia) i Pythona 3.9 na tym urządzeniu.

Nazwa testu Python 3.8 Python 3.9
2to3 286 ms 281 ms (1.02x szybciej)
async_generators 255 ms 249 ms (1.02x szybciej)
async_tree_cpu_io_mixed 709 ms 708 ms (nieistotne)
async_tree_io 1.17 sec 1.17 sec (nieistotne)
async_tree_memoization 574 ms 583 ms (nieistotne)
async_tree_none 460 ms 479 ms (1.04x wolniej)
asyncio_tcp 944 ms 912 ms (1.04x szybciej)
asyncio_tcp_ssl 2.29 sec 2.24 sec (1.02x szybciej)
bench_mp_pool 87.9 ms 92.4 ms (1.05x wolniej)
bench_thread_pool 1.21 ms 1.20 ms (nieistotne)
chameleon 11.6 ms 6.93 ms (1.67x szybciej)
chaos 70.1 ms 69.2 ms (1.01x szybciej)
comprehensions 17.8 us 16.3 us (1.09x szybciej)
coroutines 28.2 ms 25.4 ms (1.11x szybciej)
coverage 26.1 ms 25.2 ms (1.03x szybciej)
create_gc_cycles 861 us 883 us (1.03x wolniej)
crypto_pyaes 73.8 ms 70.5 ms (1.05x szybciej)
dask 440 ms 436 ms (nieistotne)
deepcopy 296 us 288 us (1.03x szybciej)
deepcopy_memo 32.5 us 31.2 us (1.04x szybciej)
deepcopy_reduce 2.53 us 2.52 us (nieistotne)
deltablue 4.49 ms 4.50 ms (nieistotne)
django_template 34.1 ms 34.6 ms (nieistotne)
docutils 2.03 sec 2.08 sec (1.02x wolniej)
dulwich_log 56.7 ms 57.7 ms (1.02x wolniej)
fannkuch 297 ms 289 ms (1.03x szybciej)
float 74.7 ms 73.1 ms (1.02x szybciej)
gc_traversal 1.74 ms 1.69 ms (1.02x szybciej)
generators 35.5 ms 34.4 ms (1.03x szybciej)
genshi_text 21.3 ms 21.1 ms (1.01x szybciej)
genshi_xml 160 ms 157 ms (1.50x szybciej)
hexiom 6.07 ms 5.86 ms (1.04x szybciej)
html5lib 55.5 ms 56.1 ms (nieistotne)
json_dumps 9.12 ms 8.96 ms (1.02x szybciej)
json_loads 22.6 us 16.5 us (1.37x szybciej)
logging_format 7.35 us 7.50 us (1.02x wolniej)
logging_silent 110 ns 110 ns (nieistotne)
logging_simple 6.94 us 6.97 us (nieistotne)
mako 11.0 ms 10.5 ms (1.05x szybciej)
mdp 1.93 sec 1.99 sec (1.03x wolniej)
meteor_contest 81.6 ms 81.9 ms (nieistotne)
nbody 78.6 ms 81.5 ms (1.04x wolniej)
nqueens 73.5 ms 69.8 ms (1.05x szybciej)
pathlib 75.3 ms 74.6 ms (nieistotne)
pickle 7.56 us 7.89 us (1.04x wolniej)
pickle_dict 20.0 us 20.0 us (nieistotne)
pickle_list 3.07 us 3.01 us (1.02x szybciej)
pickle_pure_python 295 us 292 us (1.01x szybciej)
pidigits 167 ms 170 ms (1.02x wolniej)
pprint_pformat 1.06 sec 1.05 sec (1.01x szybciej)
pyflate 471 ms 471 ms (nieistotne)
python_startup 25.1 ms 25.1 ms (nieistotne)
python_startup_no_site 19.9 ms 19.8 ms (nieistotne)
raytrace 304 ms 301 ms (1.01x szybciej)
regex_compile 112 ms 112 ms (nieistotne)
regex_dna 153 ms 147 ms (1.04x szybciej)
regex_effbot 1.86 ms 1.78 ms (1.04x szybciej)
regex_v8 17.1 ms 16.5 ms (1.04x szybciej)
richards 42.5 ms 41.1 ms (1.04x szybciej)
richards_super 53.2 ms 51.7 ms (1.03x szybciej)
scimark_fft 212 ms 211 ms (nieistotne)
scimark_lu 88.4 ms 87.0 ms (1.02x szybciej)
scimark_monte_carlo 66.7 ms 65.7 ms (1.02x szybciej)
scimark_sor 114 ms 111 ms (1.03x szybciej)
scimark_sparse_mat_mult 2.99 ms 2.95 ms (1.01x szybciej)
spectral_norm 86.6 ms 86.0 ms (1.01x szybciej)
sqlalchemy_declarative 115 ms 115 ms (nieistotne)
sqlalchemy_imperative 13.0 ms 13.3 ms (1.02x wolniej)
sqlglot_normalize 217 ms 207 ms (1.05x szybciej)
sqlglot_optimize 41.3 ms 41.0 ms (1.01x szybciej)
sqlglot_parse 1.39 ms 1.38 ms (1.01x szybciej)
sqlglot_transpile 1.64 ms 1.62 ms (1.02x szybciej)
sqlite_synth 2.35 us 2.26 us (1.04x szybciej)
sympy_expand 336 ms 352 ms (1.05x wolniej)
sympy_integrate 16.6 ms 16.7 ms (1.01x wolniej)
sympy_str 207 ms 212 ms (1.02x wolniej)
sympy_sum 116 ms 115 ms (nieistotne)
telco 4.24 ms 4.38 ms (1.03x wolniej)
tomli_loads 1.78 sec 1.75 sec (1.02x szybciej)
tornado_http 140 ms 142 ms (1.01x wolniej)
typing_runtime_protocols 374 us 361 us (1.04x szybciej)
unpack_sequence 39.6 ns 40.9 ns (1.03x wolniej)
unpickle 10.7 us 9.05 us (1.18x szybciej)
unpickle_list 2.98 us 2.99 us (nieistotne)
unpickle_pure_python 233 us 199 us (1.17x szybciej)
xml_etree_generate 73.5 ms 59.5 ms (1.24x szybciej)
xml_etree_iterparse 75.3 ms 69.7 ms (1.08x szybciej)
xml_etree_parse 122 ms 113 ms (1.08x szybciej)
xml_etree_process 57.7 ms 54.6 ms (1.06x szybciej)
Wynik (Średnia geometryczna) 1.03x szybciej

Przeprowadzona analiza wskazuje na to, że Python 3.9 ma najlepsze wyniki wydajnościowe w porównaniu do Pythona 3.8 w następujących testach: chameleon (1.67x szybciej), genshi_xml (1.50x szybciej), json_loads (1.37x szybciej). Można jednak zauważyć spadek wydajności w niektórych testach, szczególnie w bench_mp_pool (1.05x wolniej), sympy_expand (1.05x wolniej), async_tree_none (1.04x wolniej).

Dodatkowo można sprawdzić różnice w wydajności pomiędzy Pythonem 3.9 i Pythonem 3.8 w oparciu o testy należące do określonych grup. Poniższa tabela przedstawia średnią geometryczną dla testów porównawczych w ramach poszczególnych grup dla Pythona 3.9 w porównaniu z Pythonem 3.8.

Grupa testów Python 3.9 w porównaniu do Pythona 3.8
apps 1.10x szybciej
asyncio 1.01x wolniej
math 1.01x wolniej
regex 1.03x szybciej
serialize 1.08x szybciej
template 1.12x szybciej
Polski
English
Русский