Observation
Every child container allocates its own threading.RLock. On this machine that is 107 ns of an 829 ns child build (13%), paid per request. The lock guards only singleton creation on a cache miss, which is rare after warm-up and already double-checked.
Proposal
One lock per tree, created at the root and shared by children (a child stores the reference, as it already does for the shared registries). use_lock goes away; a tree is always locked, and the cost is a pointer copy. Contention: concurrent cold misses across requests would serialise on one lock instead of per child, which is what the lock is for anyway.
Needs before it is ready
An end-to-end measurement on G6 (child build) and G15 (concurrent first-resolve, the contention scenario), plus a pass over the free-threading tests. The 107 ns figure is a microbenchmark of RLock() alone.
Out of scope
The _scope_map copy (another ~95 ns per child): walking parent_container instead moves the cost onto every cross-scope hop, and the trade is workload-dependent.
Observation
Every child container allocates its own
threading.RLock. On this machine that is 107 ns of an 829 ns child build (13%), paid per request. The lock guards only singleton creation on a cache miss, which is rare after warm-up and already double-checked.Proposal
One lock per tree, created at the root and shared by children (a child stores the reference, as it already does for the shared registries).
use_lockgoes away; a tree is always locked, and the cost is a pointer copy. Contention: concurrent cold misses across requests would serialise on one lock instead of per child, which is what the lock is for anyway.Needs before it is ready
An end-to-end measurement on G6 (child build) and G15 (concurrent first-resolve, the contention scenario), plus a pass over the free-threading tests. The 107 ns figure is a microbenchmark of
RLock()alone.Out of scope
The
_scope_mapcopy (another ~95 ns per child): walkingparent_containerinstead moves the cost onto every cross-scope hop, and the trade is workload-dependent.