Pewarta Proxy

📋 Server Request & Proxy Logs

Loading active proxy settings...
Developed by Khairul Adha (adhexa.id)
Mengambil log server...

⚙️ Pengaturan Proxy Target

Skip to content

Speed up field lookup for wide Struct maps - #1291

Draft
Siyet wants to merge 2 commits into
mainfrom
speed-up-struct-field-lookup
Draft

Siyet wants to merge 2 commits into
mainfrom
speed-up-struct-field-lookup

Conversation

@Siyet

@Siyet Siyet commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

Wide Struct maps with reverse or shuffled keys repeatedly scan field names after the expected-field comparison fails. Add a lazy shared StrLookup for map Structs with at least 64 fields, while retaining that comparison and the linear fallback for input keys longer than 64 UTF-8 bytes. Build the table during type preparation, protect initialization with a CPython critical section, traverse/clear it with the class, and recheck cached type information after reentrant allocations.

Adds semantic tests across JSON, MessagePack, TOML, YAML and convert, plus JSON/MessagePack benchmarks in the existing performance suite. No public API changes. Related: #4 and #119.

Measured on a new cloud VM with 6 dedicated vCPU under KVM, using one pinned core per microbenchmark: CPython 3.14.7 with GIL, GCC 14.2.0, identical Linux x86-64 builds. The C source in this PR matches the measured candidate. For 256 fields:

Format Reverse speedup Shuffled speedup
JSON 25.60x 13.44x
TOML 1.28x 1.14x
YAML 1.20x 1.10x
MessagePack 33.24x 17.08x
Full matrix: change in mean decoding time, candidate versus base

Negative values mean faster. Each row includes all three input orders.

Format Fields Ordered Reverse Shuffled
JSON 8 +0.27% +0.02% -0.46%
JSON 16 +0.41% -0.20% +0.18%
JSON 32 -0.03% -0.25% -0.02%
JSON 64 -0.44% -84.19% -70.97%
JSON 128 -1.06% -92.06% -84.48%
JSON 256 -0.22% -96.09% -92.56%
TOML 8 +0.37% +0.03% +0.04%
TOML 16 -2.44% -0.59% -1.43%
TOML 32 +0.09% +0.74% -0.36%
TOML 64 +0.77% -6.62% -2.28%
TOML 128 -0.55% -12.04% -6.77%
TOML 256 -0.51% -22.00% -12.16%
YAML 8 +0.62% +1.03% +0.74%
YAML 16 +0.46% -0.76% -0.56%
YAML 32 -0.39% -1.14% -0.59%
YAML 64 -1.35% -5.34% -2.60%
YAML 128 +0.05% -9.32% -5.03%
YAML 256 -0.44% -16.92% -8.99%
MessagePack 8 -1.27% +1.43% +1.10%
MessagePack 16 -1.54% +0.89% +1.30%
MessagePack 32 -0.10% +0.89% +1.60%
MessagePack 64 -1.56% -87.09% -75.70%
MessagePack 128 -1.34% -93.75% -87.60%
MessagePack 256 -1.91% -96.99% -94.15%

The 72 cases use flat Structs with ASCII keys field_0000 onward, integer values of 1 and a fixed shuffle seed of 42; separate unique-value controls verify field routing. JSON/MessagePack use prepared Decoders; TOML/YAML include parsing and conversion (stdlib tomllib, PyYAML 6.0.3 CSafeLoader). Type/Decoder setup is excluded; instance allocation is included. Two rounds alternate A/B/B/A and B/A/A/B, with 576 jobs and 80 timed values per arm/case, using pyperf.

The gains apply to wide unordered inputs, not applications generally. Small unordered MessagePack cases still take up to 1.60% longer; ordered MessagePack means are 0.10-1.91% lower here, with mixed round signs at 32 fields. All observations are retained, including 288 jobs with pyperf warnings and two flagged for throttling. Worker values are clustered; small differences do not establish equivalence or portability. These results are separate from earlier ARM64 runs.

The change adds one pointer to each Struct class and an additional lazy table for wide map types; cold preparation and retained memory are not included in the timing table. Known input keys longer than the hashing cap retain linear lookup. The thresholds are implementation choices, not public guarantees.

Validation: fresh native macOS ARM64 and local Linux ARM64 builds each passed 6737 unit tests (154 skipped), including 159 new cases. Typing compatibility checks, stubtest and project hooks pass. The full Linux suite also passes ASan/UBSan (leak detection disabled). Free-threaded CPython 3.14.6 checks cover concurrent first preparation and the 159 semantic cases with the GIL disabled. Source-wide mypy produces the same 91 diagnostics as the base. Windows and GitHub CI are pending.

Closes #1289.

This branch has not been deployed

No deployments
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.

Decoding wide Structs is much slower with reversed or shuffled fields

1 participant