Version
0.10.5 (regression against 0.9.0)
Platform
macOS arm64 (48 GB, 18 CPU); measured with the shipped release binaries of both versions
Summary
The cross-file LSP pass regressed 16.6x between v0.9.0 and v0.10.5 — from 21.5 s to ~358 s on a Java corpus — and it accounts for roughly 78% of the total java indexing regression. It contributes 25,885 edges, about 0.5% of the graph, so the cost/benefit is roughly 14 ms per edge.
Measurement
Corpus: 46,477-file Java tree. Shipped binaries, same host, isolated HOME/CBM_CACHE_DIR per run, sequential (no concurrent load).
|
v0.9.0 |
v0.10.5 |
| baseline |
99.8 s |
~530 s |
CBM_DISABLE_LSP_CROSS=1 |
78.3 s |
~172 s |
| cross-LSP pass alone |
21.5 s |
~358 s (16.6x) |
| rest of the pipeline |
78.3 s |
~172 s (2.2x) |
Reproducibility: the 0.10.5 cuts were run twice — xlsp-off 175.0 s and 169.1 s; lsp-off 522.0 s and 525.2 s. Baselines 477.1 s (first sweep) and 534.5 s (recheck), so ~10% run-to-run variance, well inside the effect size.
Edge counts barely move, which is what makes the cost hard to justify as-is:
|
edges |
| 0.10.5 baseline |
5,646,309 |
0.10.5 CBM_DISABLE_LSP_CROSS=1 |
5,620,424 |
Note also that CBM_LSP_DISABLED=1 (disabling LSP entirely) barely changes wall time (522 s vs 530 s baseline) — so the cost is specifically the cross-file pass, not per-file LSP.
Reproduction
for cut in baseline xlsp-off; do
W=$(mktemp -d)
ENVV=""; [ "$cut" = "xlsp-off" ] && ENVV="CBM_DISABLE_LSP_CROSS=1"
time env HOME="$W" CBM_CACHE_DIR="$W/.cache" $ENVV ./codebase-memory-mcp cli index_repository \
--repo-path /path/to/java-corpus --mode full --name "$cut" --persistence true
done
Where to look
src/pipeline/pass_lsp_cross.c gained +628 lines between the tags, and src/pipeline/lsp_resolve.h +774, which is the natural place to start. pipeline.c already labels this "the most expensive phase", and its comment notes the old sequential implementation cost ~520 s on Kubernetes — so the parallel rewrite was supposed to be the cure here.
This may be the same root as the recorded LSP-resolve audit finding (short-name lookups bypassing QN-only buckets, and no negative memoisation), which would explain why a language with many short, heavily-overloaded method names — Java — is hit hardest.
Cross-corpus context
From the same A/B sweep (11 corpora, both versions), java is by far the worst but the regression is broad:
| corpus |
v0.9.0 |
v0.10.5 |
ratio |
| java (46,477 files) |
79.5 s |
477.1 s |
6.0x |
| csharp (58,656) |
444.3 s |
1210.8 s |
2.7x |
| typescript (81,397) |
20.7 s |
52.0 s |
2.5x |
| linux (94,769) |
243.8 s |
508.5 s |
2.1x |
| go (31,323) |
38.4 s |
60.2 s |
1.6x |
Peak RSS moved only +5–15% across all of them, so this is a throughput regression, not a memory one (the memory side is #1654, which is Linux-specific and separate).
Version
0.10.5 (regression against 0.9.0)
Platform
macOS arm64 (48 GB, 18 CPU); measured with the shipped release binaries of both versions
Summary
The cross-file LSP pass regressed 16.6x between v0.9.0 and v0.10.5 — from 21.5 s to ~358 s on a Java corpus — and it accounts for roughly 78% of the total java indexing regression. It contributes 25,885 edges, about 0.5% of the graph, so the cost/benefit is roughly 14 ms per edge.
Measurement
Corpus: 46,477-file Java tree. Shipped binaries, same host, isolated
HOME/CBM_CACHE_DIRper run, sequential (no concurrent load).CBM_DISABLE_LSP_CROSS=1Reproducibility: the 0.10.5 cuts were run twice —
xlsp-off175.0 s and 169.1 s;lsp-off522.0 s and 525.2 s. Baselines 477.1 s (first sweep) and 534.5 s (recheck), so ~10% run-to-run variance, well inside the effect size.Edge counts barely move, which is what makes the cost hard to justify as-is:
CBM_DISABLE_LSP_CROSS=1Note also that
CBM_LSP_DISABLED=1(disabling LSP entirely) barely changes wall time (522 s vs 530 s baseline) — so the cost is specifically the cross-file pass, not per-file LSP.Reproduction
Where to look
src/pipeline/pass_lsp_cross.cgained +628 lines between the tags, andsrc/pipeline/lsp_resolve.h+774, which is the natural place to start.pipeline.calready labels this "the most expensive phase", and its comment notes the old sequential implementation cost ~520 s on Kubernetes — so the parallel rewrite was supposed to be the cure here.This may be the same root as the recorded LSP-resolve audit finding (short-name lookups bypassing QN-only buckets, and no negative memoisation), which would explain why a language with many short, heavily-overloaded method names — Java — is hit hardest.
Cross-corpus context
From the same A/B sweep (11 corpora, both versions), java is by far the worst but the regression is broad:
Peak RSS moved only +5–15% across all of them, so this is a throughput regression, not a memory one (the memory side is #1654, which is Linux-specific and separate).