Skip to content

gh-154401: Skip fetching the thread state for non-GC types in _Py_Dealloc#154430

Open
johng wants to merge 1 commit into
python:mainfrom
johng:optimize-dealloc-nongc
Open

gh-154401: Skip fetching the thread state for non-GC types in _Py_Dealloc#154430
johng wants to merge 1 commit into
python:mainfrom
johng:optimize-dealloc-nongc

Conversation

@johng

@johng johng commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

@johng
johng force-pushed the optimize-dealloc-nongc branch from c4ef5f6 to e91e3d1 Compare July 22, 2026 06:47
@johng johng changed the title gh-154429: Skip fetching the thread state for non-GC types in _Py_Dealloc gh-154401: Skip fetching the thread state for non-GC types in _Py_Dealloc Jul 22, 2026
_Py_Dealloc() fetched the current thread state and computed the C
recursion margin on every deallocation, but both are only used by the
trashcan mechanism, which applies only to GC-tracked types. Gate them
behind the Py_TPFLAGS_HAVE_GC check so the common non-GC case (int,
float, str and similar atomic types) skips them.

On platforms where _PyThreadState_GET() reads a _Thread_local via a
function call (e.g. macOS TLV), this removes a call from every non-GC
deallocation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@johng
johng force-pushed the optimize-dealloc-nongc branch from e91e3d1 to 8a4463e Compare July 22, 2026 06:51
@johng

johng commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

Raised via AI, have been verifying findings as best I can

@sergey-miryanov

Copy link
Copy Markdown
Contributor

You have to show full comparison report between main and this PR from pyperformance suite.

@sergey-miryanov

Copy link
Copy Markdown
Contributor

Changes look good to me, waiting to see results from pyperformance.

@johng

johng commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

Benchmarks: this change vs main

pyperformance 1.14.0, free-threaded (--disable-gil), --with-lto=no, no PGO. Curated 33-benchmark dep-free subset (the C-extension benchmarks don't install on a free-threaded 3.16-alpha yet). The two interpreters were run sequentially (main, then the change) on untuned machines.

Raw pyperf JSON (all four runs): https://gist.github.com/johng/7a9999d11e432f6d4f455457248b4c9f

arm64 / macOS (M-series, 18 CPU) — geometric mean 1.01x faster (15 significant faster, 2 significant slower)
Benchmark main A2 (change) Change Significance
chaos 29.9 ms 29.1 ms 1.03x faster Significant (t=6.90)
comprehensions 7.50 us 7.34 us 1.02x faster Significant (t=4.56)
coroutines 11.0 ms 10.7 ms 1.02x faster Significant (t=5.20)
crypto_pyaes 42.0 ms 41.8 ms 1.01x faster Not significant
deepcopy 118 us 114 us 1.03x faster Significant (t=4.36)
deepcopy_memo 11.6 us 11.3 us 1.02x faster Significant (t=6.83)
deepcopy_reduce 1.27 us 1.24 us 1.02x faster Significant (t=4.06)
deltablue 1.68 ms 1.62 ms 1.04x faster Significant (t=7.85)
fannkuch 176 ms 165 ms 1.07x faster Significant (t=6.25)
float 33.8 ms 32.2 ms 1.05x faster Significant (t=13.25)
generators 18.5 ms 18.2 ms 1.02x faster Not significant
go 52.8 ms 52.3 ms 1.01x faster Not significant
hexiom 2.94 ms 2.95 ms 1.00x slower Not significant
json_dumps 4.09 ms 4.11 ms 1.01x slower Not significant
json_loads 14.0 us 14.1 us 1.00x slower Not significant
logging_format 2.66 us 2.65 us 1.00x faster Not significant
logging_silent 42.2 ns 41.9 ns 1.01x faster Not significant
logging_simple 2.41 us 2.42 us 1.00x slower Not significant
meteor_contest 48.4 ms 48.9 ms 1.01x slower Not significant
nbody 55.5 ms 54.6 ms 1.02x faster Not significant
nqueens 36.2 ms 36.8 ms 1.02x slower Not significant
pickle 5.82 us 5.84 us 1.00x slower Not significant
pickle_dict 13.2 us 13.1 us 1.01x faster Not significant
pickle_list 2.39 us 2.40 us 1.00x slower Not significant
pprint_pformat 729 ms 742 ms 1.02x slower Not significant
pprint_safe_repr 356 ms 359 ms 1.01x slower Not significant
pyflate 183 ms 184 ms 1.01x slower Not significant
raytrace 134 ms 132 ms 1.01x faster Not significant
regex_compile 57.5 ms 57.7 ms 1.00x slower Not significant
regex_dna 86.2 ms 85.1 ms 1.01x faster Not significant
regex_effbot 1.28 ms 1.25 ms 1.03x faster Significant (t=7.63)
regex_v8 9.35 ms 9.09 ms 1.03x faster Significant (t=12.39)
richards 25.0 ms 24.4 ms 1.03x faster Significant (t=8.46)
scimark_fft 150 ms 144 ms 1.04x faster Significant (t=11.74)
scimark_lu 55.8 ms 54.8 ms 1.02x faster Not significant
scimark_monte_carlo 31.6 ms 31.4 ms 1.00x faster Not significant
scimark_sor 52.5 ms 52.1 ms 1.01x faster Not significant
scimark_sparse_mat_mult 2.50 ms 2.40 ms 1.04x faster Significant (t=8.17)
spectral_norm 47.5 ms 45.9 ms 1.04x faster Significant (t=14.45)
telco 3.14 ms 3.22 ms 1.03x slower Significant (t=-8.14)
unpack_sequence 16.5 ns 17.1 ns 1.03x slower Significant (t=-14.47)
unpickle 7.38 us 7.52 us 1.02x slower Not significant
x86-64 / Linux (2 vCPU) — geometric mean 1.02x faster (16 significant faster, 3 significant slower)
Benchmark main A2 (change) Change Significance
chaos 102 ms 101 ms 1.01x faster Not significant
comprehensions 27.5 us 27.9 us 1.02x slower Not significant
coroutines 36.9 ms 35.0 ms 1.05x faster Not significant
crypto_pyaes 144 ms 140 ms 1.03x faster Not significant
deepcopy 455 us 467 us 1.03x slower Not significant
deepcopy_memo 48.0 us 46.5 us 1.03x faster Not significant
deepcopy_reduce 5.81 us 5.40 us 1.08x faster Significant (t=2.88)
deltablue 5.83 ms 5.80 ms 1.01x faster Not significant
fannkuch 630 ms 643 ms 1.02x slower Not significant
float 135 ms 129 ms 1.04x faster Significant (t=2.79)
generators 51.6 ms 54.5 ms 1.06x slower Significant (t=-2.27)
go 187 ms 176 ms 1.07x faster Significant (t=2.29)
hexiom 9.86 ms 9.88 ms 1.00x slower Not significant
json_dumps 17.2 ms 17.3 ms 1.00x slower Not significant
json_loads 41.3 us 39.4 us 1.05x faster Significant (t=3.34)
logging_format 12.4 us 11.3 us 1.10x faster Significant (t=3.14)
logging_silent 150 ns 148 ns 1.01x faster Not significant
logging_simple 10.0 us 10.2 us 1.01x slower Not significant
meteor_contest 173 ms 170 ms 1.02x faster Not significant
nbody 195 ms 166 ms 1.18x faster Significant (t=5.98)
nqueens 150 ms 148 ms 1.01x faster Not significant
pickle 19.0 us 18.9 us 1.01x faster Not significant
pickle_dict 45.4 us 45.4 us 1.00x faster Not significant
pickle_list 9.04 us 8.79 us 1.03x faster Not significant
pprint_pformat 3.01 sec 3.05 sec 1.01x slower Not significant
pprint_safe_repr 1.43 sec 1.47 sec 1.03x slower Not significant
pyflate 673 ms 677 ms 1.01x slower Not significant
raytrace 489 ms 472 ms 1.04x faster Significant (t=3.15)
regex_compile 267 ms 255 ms 1.04x faster Significant (t=2.21)
regex_dna 253 ms 249 ms 1.01x faster Not significant
regex_effbot 3.72 ms 3.82 ms 1.03x slower Significant (t=-2.02)
regex_v8 30.8 ms 29.0 ms 1.06x faster Significant (t=3.14)
richards 80.3 ms 85.9 ms 1.07x slower Significant (t=-3.03)
scimark_fft 534 ms 499 ms 1.07x faster Significant (t=3.07)
scimark_lu 219 ms 230 ms 1.05x slower Not significant
scimark_monte_carlo 132 ms 124 ms 1.06x faster Significant (t=2.48)
scimark_sor 206 ms 193 ms 1.07x faster Significant (t=4.03)
scimark_sparse_mat_mult 8.88 ms 8.23 ms 1.08x faster Significant (t=4.84)
spectral_norm 163 ms 156 ms 1.04x faster Significant (t=5.07)
telco 310 ms 292 ms 1.06x faster Significant (t=2.68)
unpack_sequence 60.4 ns 60.1 ns 1.00x faster Not significant
unpickle 25.9 us 25.3 us 1.02x faster Significant (t=2.07)

@johng
johng marked this pull request as ready for review July 22, 2026 17:59
@johng
johng requested a review from ZeroIntensity as a code owner July 22, 2026 17:59
@johng

johng commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

@sergey-miryanov please see above for the table of results, and also link to gist of raw json too

@sergey-miryanov

Copy link
Copy Markdown
Contributor

It would be good to see results with enabled PGO+LTO, and for GIL-enabled build.
Also, it would be good to see comparison table from pyperf compare_to command.

@ZeroIntensity ZeroIntensity left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 7% slowdown on x86-64 richards is a little concerning, but I suspect that's just noise. I can't imagine how this would possibly slow things down, because we're not adding any additional checks beyond what was already there.

@johng

johng commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

Thanks!

Added the three way comparison for both arch's https://gist.github.com/johng/388e14f9a40c88f8a2031f2383f6938d

Likely need to find a better x86 host in the future, there's likely a bit too much noise but no trends either way for that arch as expected. Arm I think is showing a consistent small speedup across the tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants