Commit 40b6bd4
authored
perf: cache InstrLocation across consecutive positions (#202)
In ConcreteBytecode.from_code, InstrLocation._from_tuple is called once
per instruction to construct a location object from the (lineno,
end_lineno, col_offset, end_col_offset) tuple yielded by co_positions().
This was 5.31% of total CPU time in profiling.
Python bytecodes for a single source expression (e.g. a + b, a for loop
header, a CACHE entry) all map to the same source position. Because of
this structural property, position tuples repeat frequently and tend to
be contiguous — consecutive instructions usually share the same position.
In the dis module corpus, 78.4% of the 860 position tuples are repeated.
A single-entry cache (remember the last pos/loc pair) turns most
iterations into a cheap tuple equality check, avoiding object.__new__ +
4x object.__setattr__ for the common case. A full dict cache was also
tried but was slower: the per-iteration dict hash + lookup costs more
than tuple equality even though it has a higher hit rate.
Performance analysis (own time):
| Hotspot | Before | After |
|---|---|---|
| InstrLocation._from_tuple own | 5.31% | 1.55% |
Code object analysis (dis module)
| Metric | Value |
|---|---|
| Total position tuples | 860 |
| Unique positions | 318 (37%) |
| Repeated positions | 542 (63%) |
Throughput (Bytecode.from_code().to_code() on dis module, 30 runs each)
with Mann-Whitney U Test
| Approach | p95 | vs baseline |
|---|---|---|
| Baseline (main) | 180 r/s | — |
| Dict cache | 190 r/s | +5.6% (✓ significant, p≈0) |
| Single-entry cache | 192 r/s | +6.7% (✓ significant, p≈0) |1 parent 41c679b commit 40b6bd4
1 file changed
Lines changed: 10 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
380 | 380 | | |
381 | 381 | | |
382 | 382 | | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
383 | 387 | | |
384 | 388 | | |
385 | 389 | | |
386 | 390 | | |
387 | | - | |
388 | | - | |
389 | | - | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
390 | 397 | | |
391 | 398 | | |
392 | 399 | | |
| |||
0 commit comments