Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Perf: specialized LOAD_ATTR handlers still do full dict probes (hint unused, no keys-version shadow check) #42

Copy link
Copy link

Description

@youknowone
Issue body actions

Status update (2026-07-22)

The specialization blocker tracked in #41 is fixed — LOAD_ATTR now specializes for plain user classes — so the probes described here are no longer hypothetical: they are the active ceiling on attribute-heavy code. Verified at dd9bce5 that all three findings below still hold (line numbers refreshed).

Fresh profile evidence (Apple M5 Max, release build; see #41 for methodology): in a function-scoped s += c.x loop, Dict::get<PyInterned<PyStr>> inside LoadAttrInstanceValue alone is ~7% of samples, and overall attribute-read overhead is still ~11.5x CPython 3.14 (25.4ns vs 2.2ns).

Problem

Even when LOAD_ATTR does specialize, the specialized handlers still perform a full dict hash-probe per execution, where CPython's equivalents are a couple of integer compares.

Causes

crates/vm/src/frame.rs, specialized handlers (line numbers at dd9bce5):

  1. LoadAttrWithHint (~4481) ignores its hint. It runs dict.get_item_opt(attr_name, vm) — a complete hash + probe — every time. The dict already supports exactly the needed API: LoadGlobalModule uses get_item_opt_hint(name, cached_index, vm) (~6319) with a cached entry index + dict version, skipping the probe on hit. The instance-attr path never got the same treatment — the specializer (~8432–8438) writes only the type version into the cache, no entry index.

  2. LoadAttrMethodWithValues (~4424) does a full dict probe as its shadow check. To verify the method isn't shadowed by an instance attribute it runs dict.get_item_opt(attr_name, vm) on the instance dict per call (~4434–4445). CPython's LOAD_ATTR_METHOD_WITH_VALUES compares the cached dict keys version (a single u32) — possible because unmodified instances of the same class share a keys object. RustPython dicts have a version() counter (dict_inner.rs ~266) that could be cached per-site: if dict.version() == cached_version { not shadowed }, falling back to the probe only when the dict changed.

  3. LoadAttrInstanceValue (~4459) likewise re-hashes the name each time. There is no split-keys/managed-dict layout, so "read attribute" can't be "load values[offset]" like CPython's LOAD_ATTR_INSTANCE_VALUE; at minimum it can use the hint mechanism from (1).

  4. StoreAttrInstanceValue/StoreAttrWithHint (~4714–4751) have the same shape: type-version guard, then a full dict.set_item hash + probe per execution.

Suggested direction

Short term (no dict redesign):

  • Store an entry-index hint + dict version in the LOAD_ATTR inline cache (there are 9 cache slots) and use get_item_opt_hint in LoadAttrWithHint/LoadAttrInstanceValue.
  • Replace the MethodWithValues shadow probe with a cached dict-version compare, re-probing only on version mismatch.
  • Same idea applies to StoreAttr* handlers.

Longer term:

  • CPython-style split keys (shared keys object per class + per-instance values array) would make instance attr access a version check + indexed load, and would also shrink per-instance memory. This is a big change to dictdatatype/object layout and interacts with free-threading (CPython 3.13t keeps split keys with per-object locking), so it deserves its own design pass after the short-term wins land.

Researched and written by Claude on behalf of @youknowone. Part of the performance tracking series.

Part of #38.

Reactions are currently unavailable

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    Morty Proxy This is a proxified and sanitized view of the page, visit original site.