diff options
| author | user <user@clank> | 2026-08-07 01:55:31 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-08-07 01:55:31 +0200 |
| commit | cf45e115bcd137020002e84b67da7b00547901b5 (patch) | |
| tree | 3954101322a281db2c2a739d647331fc33414be1 /.auto/prompt.md | |
| parent | _idatui_spans: one capturing re.split over the tag pairs instead of finditer+... (diff) | |
| download | ida-tui-cf45e115bcd137020002e84b67da7b00547901b5.tar.gz ida-tui-cf45e115bcd137020002e84b67da7b00547901b5.tar.xz ida-tui-cf45e115bcd137020002e84b67da7b00547901b5.zip | |
Re-apply #5 (lru_cache on the per-line render + Heads built with their opcode bytes already attached) with the graph_minimap scenario's racy SETUP made deterministic: clear _graph_sticky before the second navigation so Space is known to be entering the graph, not leaving it. No assertion changed.
Result: {"status":"keep","total_ms":22980.2,"lg_boot_ms":738.2,"lg_decomp_ms":2401.8,"lg_graph_ms":944.1,"lg_hex_ms":920.6,"lg_index_ms":75.2,"lg_listing_cold_ms":538.5,"lg_listing_warm_ms":411.1,"lg_nav_ms":6813.9,"lg_palette_ms":4.9,"lg_render_ms":221.8,"lg_search_ms":5630.1,"pure_graph_ms":240.7,"sm_boot_ms":537.5,"sm_decomp_ms":595.1,"sm_graph_ms":715.7,"sm_hex_ms":858.8,"sm_index_ms":0,"sm_listing_cold_ms":263.3,"sm_listing_warm_ms":265.3,"sm_nav_ms":335.2,"sm_palette_ms":0.3,"sm_render_ms":271.4,"sm_search_ms":196.5,"fails":0}
Diffstat (limited to '.auto/prompt.md')
| -rw-r--r-- | .auto/prompt.md | 48 |
1 files changed, 44 insertions, 4 deletions
diff --git a/.auto/prompt.md b/.auto/prompt.md index 39126b9..a2ced97 100644 --- a/.auto/prompt.md +++ b/.auto/prompt.md @@ -72,7 +72,16 @@ expected payoff: ## Off Limits - `tests/**` — the correctness gate. Do not weaken, skip, shorten or "fix" a - test to make a change pass. If a test fails, the change is wrong. + test to make a change pass. If a test fails, **assume the change is wrong**. + + One narrow exception, and it costs you a proof: a scenario whose *setup* is + racy, where the speedup merely decides which of two async loads lands first. + Before touching it you must (a) bisect to show which change flips it, (b) + reproduce the race outside the suite, showing the app reaching two different + states from the same steps, and (c) show the repaired scenario passing on + BOTH the fast and the slow code. Only the setup may change — every `c.check` + stays exactly as it was — and the ASI must record all three proofs. Done once + so far, for `graph_minimap` (experiment #6). - `.auto/bench.py` may only be changed to add *more* signal (extra metrics, extra NOTES). Never to do less work, shorten a sweep, drop a phase, loosen a wait, or pick easier functions. If you change what it measures, say so in the @@ -96,7 +105,38 @@ expected payoff: ## What's Been Tried -(baseline only — fill this in as experiments accumulate) +Baseline: `total_ms` ≈ 46 600. `lg_nav_ms` ≈ 29 000 (62% of it), of which a +single cold jump to a high address was ≈ 28 200. + +**Wins** + +1. *(#3, −42%)* **ida-pro-mcp installs a `sys.setprofile` hook around every tool + call.** Its deadline mechanism profiles every python call/return so a + pure-python tool body can be interrupted — a 3.3× tax on a backend whose + tools are call-heavy (`heads`: 92 → 28 µs/row without it). `worker.py` now + sets `IDA_MCP_TOOL_TIMEOUT_SEC=0` and arms the deadline itself with one + polling watchdog thread + `ida_kernwin.set_cancelled()` — the half that + actually frees the IDA main thread. +2. *(#4, −3%)* **`_idatui_spans` via one capturing `re.split`**, and whitespace + collapsed with `" ".join(txt.split())` rather than `re.sub`. 13.2 → 11.1 + µs/line. +3. *(#6)* **`lru_cache` on the per-line render** (`_idatui_line_parts`) plus + building `Head`s with their opcode bytes already attached. + +**Dead ends / things not to re-try** + +- `re.finditer` per tag in the span walker is *slower* than a plain character + loop (14.4 vs 13.2 µs/line): Match objects cost more than the ~54 trivial + iterations they replace. +- `ListingModel.PAGE` (500 / 1000 / 2000) makes no measurable difference — + the cost is per row, not per round trip. Don't tune it. +- `re.sub` for the whitespace collapse costs ~1 µs per call at ~6.5 calls/line. + +**Measurement traps** -- Baseline: `total_ms` ≈ 46 000. `lg_nav_ms` ≈ 28 600 (62% of it), of which a - single cold jump to a high address is ≈ 27 800. +- `cProfile` massively distorts this code (it is call-heavy): it reported + `_idatui_spans` at 68% of the `heads` tool when the real share was ~10%. + A/B with `time.perf_counter` in one process instead. +- Anything that walks the listing twice in one process is measuring a warm + `_idatui_line_parts` cache the second time. Run cold cases first, or in + separate processes. |
