Skip to content

gh-150942: Speed up FrameLocalsProxy.values() - #156055

Open
catlover-bot wants to merge 1 commit into
python:mainfrom
catlover-bot:perf-framelocalsproxy-values-takeref
Open

gh-150942: Speed up FrameLocalsProxy.values()#156055
catlover-bot wants to merge 1 commit into
python:mainfrom
catlover-bot:perf-framelocalsproxy-values-takeref

Conversation

@catlover-bot

Copy link
Copy Markdown

Summary

Speed up FrameLocalsProxy.values() by using
_PyList_AppendTakeRef() when adding values returned by
framelocalsproxy_getval().

framelocalsproxy_getval() returns a new reference. Previously,
PyList_Append() added another reference to the value and the original
reference was then decremented by the caller.

Using _PyList_AppendTakeRef() transfers the existing reference directly
to the result list, avoiding the unnecessary incref/decref pair while
preserving ownership and error handling.

Benchmarks

Benchmarks used pyperf 2.10.0 with CPython 3.16.0a0 built using
--enable-optimizations --with-lto.

Environment:

  • Linux x86-64 on WSL2
  • Intel Core i5-1135G7
  • GCC 13.3.0
  • benchmark process pinned to CPU 2

FrameLocalsProxy.values() microbenchmark

Frames contained ordinary heap objects rather than immortal small
integers.

Locals Baseline Patched Change
8 120 ns 105 ns 1.14x faster
32 337 ns 264 ns 1.27x faster
128 1.13 us 1.03 us 1.10x faster
256 2.23 us 2.01 us 1.11x faster
geometric mean reference 1.15x faster

An earlier independent run produced a 1.16x geometric-mean speedup.

Tracing/debugger-like workload

A sys.settrace() workload was also tested where the trace function
enumerates frame.f_locals.values() on line events.

Locals Baseline Patched Result
32 68.4 us 69.3 us not significant
128 127 us 125 us not significant
256 189 us 181 us 1.04x faster

The improvement is mostly hidden by surrounding tracing overhead in the
smaller workloads, while the 256-local case still shows a measurable
improvement.

Validation

  • python -m test test_frame: passed
  • python -m test -R 3:3 test_frame: passed
  • reference ownership test: passed
  • optimized-build semantic smoke test: passed
  • git diff --check: passed

AI assistance was used while investigating this issue, designing the
benchmarks, and preparing the change. I reviewed the implementation,
reference ownership semantics, benchmark methodology, and test results
myself.

@bedevere-app

bedevere-app Bot commented Aug 19, 2026

Copy link
Copy Markdown

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@python-cla-bot

python-cla-bot Bot commented Aug 19, 2026

Copy link
Copy Markdown

All commit authors signed the Contributor License Agreement.

CLA signed

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.

1 participant