• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

aio-libs / multidict / 36020212647
87%

Build:
DEFAULT BRANCH: master
Ran 24 Sep 2026 03:27PM UTC
Jobs 1
Files 43
Run time 1min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

24 Sep 2026 03:26PM UTC coverage: 87.672%. Remained the same
36020212647

push

github

web-flow
Compare the hash before taking a reference in the lock-free probes (#1570)

<!-- Thank you for your contribution! -->

## What do these changes do?

On the free-threaded build `d[key]`, `d.get()`, `d.getone()` and
`key in d` probe the table without the critical section, and for every
entry on the probe chain took a reference to the entry's identity with
`try_get_ref()` (an atomic load, a `TryIncRef`, a re-load and a
`Py_DECREF`) before even comparing hashes. The two lock-free probes now
compare the hash first, so a mismatch costs no reference traffic, and
treat an identity that is the very same object as the one being looked
up as a match without taking the reference: the caller's own reference
keeps that object alive, so its address cannot have been reused for
anything else. Only an identity that is a different object still goes
through `try_get_ref()` for the string compare, and the `NULL` and
`_MD_NEED_LOCK` fallbacks are unchanged.

The GIL build has no lock-free probe and is untouched; the pure-Python
implementation has nothing corresponding.

Instruction counts per operation, `benchmarks/callgrind_driver.py`,
CPython 3.14.7t, `PYTHONHASHSEED=0`:

| operation, free-threaded | `MultiDict` before | after | |
`CIMultiDict` before | after | |
| --- | ---: | ---: | ---: | ---: | ---: | ---: |
| `d[key]` | 291 | 249 | -14% | 378 | 336 | -11% |
| `key in d` | 253 | 209 | -18% | 340 | 295 | -13% |
| `d.get(key)`, miss | 409 | 388 | -5% | 660 | 639 | -3% |
| `d[istr]` | | | | 292 | 250 | -14% |
| `d.update(other)`, 100 existing keys | 48,915 | 48,283 | -1% | 57,863
| 57,251 | -1% |

`dict` on the same build: `d[key]` 224, `key in d` 235. Every other
row is unchanged to the instruction.

Wall clock, interleaved before/after runs pinned to a P-core on an idle
machine, median ns per operation:

| operation, free-threaded | `MultiDict` before | after | |
`CIMultiDict` before | after | | `dict` |
| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
| `d[ke... (continued)

777 of 1554 branches covered (50.0%)

Branch coverage included in aggregate %.

7693 of 8107 relevant lines covered (94.89%)

1.9 hits per line

Jobs
ID Job ID Ran Files Coverage
1 MyPy - 36020212647.1 24 Sep 2026 03:27PM UTC 86
87.67
GitHub Action Run
Source Files on build 36020212647
  • Tree
  • List 43
  • Changed 2
  • Source Changed 0
  • Coverage Changed 2
Coverage ∆ File Lines Relevant Covered Missed Hits/Line Branch Hits Branch Misses
  • Back to Repo
  • Github Actions Build #36020212647
  • 9d97ce56 on github
  • Prev Build on master (#36018545646)
  • Next Build on master (#36039339303)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc