Skip to content

Extend CI benchmarking with microbenchmarks for individual types - #1087

Merged
provinzkraut merged 3 commits into
msgspec:mainfrom
provinzkraut:more-performance-tests
Jun 19, 2026
Merged

provinzkraut merged 3 commits into
msgspec:mainfrom
provinzkraut:more-performance-tests

Conversation

@provinzkraut

Copy link
Copy Markdown
Member

Before, we only tested overall performance with mixed data. However, this can skew results a bit.

This introduces targeted, isolated tests for builtin types we support, to make it easier to catch regressions / test improvements for individual type handling.

@provinzkraut
provinzkraut requested a review from ofek June 18, 2026 16:33
@provinzkraut
provinzkraut force-pushed the more-performance-tests branch from 629214a to 2af241e Compare June 18, 2026 16:33
@codspeed

codspeed Bot commented Jun 18, 2026 •

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 45 untouched benchmarks
🆕 207 new benchmarks
⏩ 2 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
🆕 Simulation test_decode_convert_type_non_strict[amd-convert-float] N/A 649.1 µs N/A
🆕 Simulation test_decode_convert_type_non_strict[amd-convert-int] N/A 748.4 µs N/A
🆕 Simulation test_decode_convert_type_non_strict[amd-json-float] N/A 3.1 ms N/A
🆕 Simulation test_decode_convert_type_non_strict[amd-json-int] N/A 2.7 ms N/A
🆕 Simulation test_decode_convert_type_non_strict[amd-msgpack-float] N/A 2.2 ms N/A
🆕 Simulation test_decode_convert_type_non_strict[amd-msgpack-int] N/A 2.3 ms N/A
🆕 Simulation test_decode_type[amd-json-bytearray] N/A 105.8 µs N/A
🆕 Simulation test_decode_type[amd-json-bytes] N/A 105.4 µs N/A
🆕 Simulation test_decode_type[amd-json-date] N/A 3.1 ms N/A
🆕 Simulation test_decode_type[amd-json-datetime] N/A 3.8 ms N/A
🆕 Simulation test_decode_type[amd-json-datetimetz] N/A 4 ms N/A
🆕 Simulation test_decode_type[amd-json-decimal] N/A 18 ms N/A
🆕 Simulation test_decode_type[amd-json-dict] N/A 6 ms N/A
🆕 Simulation test_decode_type[amd-json-enum] N/A 1.2 ms N/A
🆕 Simulation test_decode_type[amd-json-False] N/A 943.9 µs N/A
🆕 Simulation test_decode_type[amd-json-float] N/A 3.1 ms N/A
🆕 Simulation test_decode_type[amd-json-frozenset] N/A 3.7 ms N/A
🆕 Simulation test_decode_type[amd-json-int] N/A 2.7 ms N/A
🆕 Simulation test_decode_type[amd-json-list] N/A 43.3 µs N/A
🆕 Simulation test_decode_type[amd-json-long_string] N/A 74.6 µs N/A
... ... ... ... ... ...

ℹ️ Only the first 20 benchmarks are displayed. Go to the app to view all benchmarks.


Comparing provinzkraut:more-performance-tests (206c13b) with main (54a7c2f)

Open in CodSpeed

Footnotes

  1. 2 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

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

Very nice!

# re-importing purely within the current interpreter doesn't get reliable timings
def do_import():
subprocess.run([sys.executable, "-c", "import msgspec"], check=True)
subprocess.run([sys.executable, "-c", f"import {module_name}"], check=True)

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.

Can you pass this to hyperfine instead? Otherwise, we really won't get reliable measurements. I'd recommended tracking just the difference/true overhead.

❯ (
    uv run --python 3.14 --no-project --isolated --with msgspec
    -- hyperfine
        --export-json -
        --style none
        --shell none
        --min-runs 100
        --warmup 10
        --reference-name baseline
        --reference 'python -c pass'
        --command-name combined
        'python -c "import msgspec"'
    err> null-device
    | from json
    | get results
    | select command median
    | update median {|r| $r.median * 1000 }
    | transpose --header-row --as-record
    | insert overhead {|r| $r.combined - $r.baseline }
)
╭──────────┬───────╮
│ baseline │ 47.02 │
│ combined │ 87.67 │
│ overhead │ 40.65 │
╰──────────┴───────╯

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Not really, no. That will work for local benchmarking, but not in CI with codspeed, where we use its CPU instrumentation, not walltime measurements.

Unfortunately I haven't found a good way yet to measure the import time without the interpreter startup overhead with codspeed.

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.

Is there no way to submit a raw value that we can track over time?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Not that I know of, no. I could look into hacking something together, but iiuc that just isn't the intended use case. codspeeds model is tuned towards running stuff you submit there. A bit unfortunate really

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

it should be fine as-is though, as we're only tracking the relative performance, not the absolute numbers, and the stability there is exactly what codspeed is attempting to solve with their CPU simulation. i'd suggest we just go with that for a while and see how it works out. with the latest changes i've made, things seem to be quite stable now though

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

Thanks!

Can you please open an issue to track startup overhead with hyperfine as conceptualized here using either Codspeed's walltime instrument or some other approach? We really just need any rudimentary way to track the overhead delta from that comment.

@provinzkraut
provinzkraut added this pull request to the merge queue Jun 19, 2026
Merged via the queue into msgspec:main with commit d3b848c Jun 19, 2026
26 checks passed
@provinzkraut
provinzkraut deleted the more-performance-tests branch June 19, 2026 16:45
@provinzkraut

Copy link
Copy Markdown
Member Author

Can you please open an issue to track startup overhead with hyperfine as conceptualized here using either Codspeed's walltime instrument or some other approach? We really just need any rudimentary way to track the overhead delta from that comment.

@ofek I think we already got #886 tracking this. I'm planning to tackle that soon

@ofek

ofek commented Jun 19, 2026

Copy link
Copy Markdown
Member

Oh that's true, thanks! Sorry to keep talking about startup overhead; it's just that I maintain a great number of CLIs and the pain there is real 😅

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