Skip to content

gh-161661: json.dumps use a single dict probe for circular-reference markers - #161662

Open
aivarsk wants to merge 1 commit into
python:mainfrom
aivarsk:json-dumps-markers-setdefault
Open

aivarsk wants to merge 1 commit into
python:mainfrom
aivarsk:json-dumps-markers-setdefault

Conversation

@aivarsk

@aivarsk aivarsk commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

One less hash calculation and lookup per circular reference check.

@aivarsk
aivarsk force-pushed the json-dumps-markers-setdefault branch from 0e056ec to 7fa0231 Compare November 9, 2026 09:24
@picnixz

picnixz commented Nov 9, 2026

Copy link
Copy Markdown
Member

This adds a Py_DECREF path which may, on free-threading, introduce refcounting contention. Can you check the impact as well please?

@aivarsk

aivarsk commented Nov 9, 2026

Copy link
Copy Markdown
Contributor Author

The synthetic test with a lot of containers there is improvement for free-threading as well but a bit smaller.
GIL: base → branch: 33.73 → 32.05 ms (-5.0%)
FT: base → branch : 40.59 → 39.08 ms (-3.7%)

@picnixz

picnixz commented Nov 9, 2026 •

Copy link
Copy Markdown
Member

What about pyperformance's JSON benchmark? And how is the synthetic benchmark done? (PGO+LTO? release build? pyperf or time? if it's timeit, use pyperf instead)

@aivarsk

aivarsk commented Nov 9, 2026

Copy link
Copy Markdown
Contributor Author

The built was just a plain -O3, no PGO+LTO. The existing pyperformance cases did show 0.x improvement but that's insignificant. Could be noise in eiter direction, as this is my laptop.
My synthetic testcase did use pyperf, just with a lot of nested containers to pressure the circular checks
jsondumps.py

@picnixz

picnixz commented Nov 9, 2026

Copy link
Copy Markdown
Member

FTR, please don't add attachments. Users usually don't want to download code so prefer using inline blocks (in a <details> section).

@picnixz picnixz 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.

I think the change could be done but at the same time, I'd prefer not touching code that has been settled for a while especially considering the lack of significant performance in either direction.

So I'll defer the final decision to @serhiy-storchaka

@nineteendo

Copy link
Copy Markdown
Contributor

How does this compare to using a set?

@aivarsk

aivarsk commented Nov 10, 2026

Copy link
Copy Markdown
Contributor Author

@nineteendo haven't tried it because markers is a dict and here it's a minimal change without API changes I came up with during #137103. If API change is on the table I think limiting recursion depth like other libraries do is the best way.

@nineteendo

Copy link
Copy Markdown
Contributor

I think you can also check the size before and after adding the element.

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

Labels

awaiting review type-feature A feature request or enhancement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants