Skip to content

test: Fix flaky cookie unquoting linear-performance test on PyPy - #3848

Merged
bdarnell merged 1 commit into
tornadoweb:masterfrom
bdarnell:claude/project-thread-642yjk
Oct 26, 2026
Merged

bdarnell merged 1 commit into
tornadoweb:masterfrom
bdarnell:claude/project-thread-642yjk

Conversation

@bdarnell

Copy link
Copy Markdown
Member

test_unquote_linear_performance failed intermittently on PyPy with a ratio just over its limit of 20. It was not timer noise: each sample is already at least 0.1s and the minimum of several. Three things were wrong:

  • assert_linear_scaling disabled the GC on every implementation. On PyPy that only stops major collections, so objects promoted out of the nursery pile up for the whole measurement (about 1MB per call here), and the larger input pays for touching fresh memory. This inflated the ratio of linear code to 20-90 depending on PYPY_GC_NURSERY. The GC is now only disabled on CPython.

  • Even without that, this test allocates heavily per input byte and its PyPy ratio depends on the nursery and cache sizes (11-24 measured), so its limit is raised to 40. The quadratic 6.4.1 implementation measures about 100 on CPython and 60-100 on PyPy.

  • The quick measurement timed n1 first, before PyPy's JIT had warmed up, which inflated it enough that the quadratic 6.4.1 implementation passed this test on PyPy. A warmup now precedes it.

Claude-Session: https://claude.ai/code/session_0168zU4yXrAsAoY3KAWuiE8n

test_unquote_linear_performance failed intermittently on PyPy with a
ratio just over its limit of 20. It was not timer noise: each sample is
already at least 0.1s and the minimum of several. Three things were
wrong:

* assert_linear_scaling disabled the GC on every implementation. On PyPy
  that only stops major collections, so objects promoted out of the
  nursery pile up for the whole measurement (about 1MB per call here),
  and the larger input pays for touching fresh memory. This inflated
  the ratio of linear code to 20-90 depending on PYPY_GC_NURSERY. The
  GC is now only disabled on CPython.

* Even without that, this test allocates heavily per input byte and its
  PyPy ratio depends on the nursery and cache sizes (11-24 measured), so
  its limit is raised to 40. The quadratic 6.4.1 implementation measures
  about 100 on CPython and 60-100 on PyPy.

* The quick measurement timed n1 first, before PyPy's JIT had warmed up,
  which inflated it enough that the quadratic 6.4.1 implementation passed
  this test on PyPy. A warmup now precedes it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0168zU4yXrAsAoY3KAWuiE8n
@bdarnell
bdarnell merged commit 57deb98 into tornadoweb:master Oct 26, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants