kate-deft/docs/PERF.md

2.8 KiB
Raw Blame History

Switcher performance — measured bottlenecks

Benchmark harness: src/project/bench_switcher.cpp (manual target bench_switcher, not a ctest). Run:

cmake -S . -B build-rel -DCMAKE_BUILD_TYPE=Release
cmake --build build-rel --target bench_switcher
./build-rel/bin/bench_switcher <project-root> /tmp/switcher_metrics.txt

Reference project: ~/prj/r7.20/mobydick — 12,234 files, 17,184 ctags symbols, 6.3 GB tree.

One-time cost when the switcher opens (UI thread, synchronous)

Stage Release Debug (shipped)
ProjectIndex::listFiles ~84 ms ~78 ms
SymbolIndex::listSymbols ~974 ms ~499 ms
build items + setItems ~5 ms ~45-70 ms
  • listFiles is a git ls-files subprocess — acceptable but blocks the UI.
  • listSymbols is a ctags subprocess (~0.5-1 s) — the dominant open-cost, and it blocks the UI thread. (Cost is in the external binary, not our parse.)

Per-keystroke cost — the interactive bottleneck

PaletteModel::setQuery → re-rank. Originally O(N) every keystroke; the cost grew with query length even as the result set shrank.

Full-scan (every keystroke re-scores all N), Release:

Query files symbols
server ~14 ms ~30 ms
src server go ~17 ms ~36 ms

Debug (what ships): 270-342 ms (files), 459-598 ms (symbols) per keystroke — unusable.

Fix 1 — incremental narrowing (done)

When a query only appends to the previous one, re-score only the currently visible subset (the match set is monotonic under lengthening/adding a needle), turning later keystrokes from O(N) into O(previous matches). Exactness is guarded by test_palettemodel::incrementalMatchesFullScan (incremental == full-scan, incl. the typo tier).

Effect once the set narrows (Release, type-forward):

Query full-scan incremental
files server ~14 ms ~6.6 ms
symbols server ~30 ms ~9.0 ms

Early keystrokes (s, se) remain full-N because almost everything matches — correct and unavoidable without a prefix index.

The shipped olliepalette.so is a Debug build (-g, no -O). Release is ~5-8× faster on every hot path above. Install a Release or RelWithDebInfo build.

Open follow-up — move indexing off the UI thread

listFiles (~85 ms) and especially listSymbols (~0.5-1 s) run synchronously when the switcher opens. For large projects they should run on a worker thread (or be cached + refreshed on KateProjectBridge::projectChanged) so the palette appears instantly and fills in as results arrive. Not yet done.