Skip to content

perf(source-map): reuse resolved segments in range queries - #108

Merged
luojiyin1987 merged 1 commit into
masterfrom
perf/reuse-resolved-segments
Sep 7, 2026
Merged

luojiyin1987 merged 1 commit into
masterfrom
perf/reuse-resolved-segments

Conversation

@luojiyin1987

@luojiyin1987 luojiyin1987 commented Sep 7, 2026 •

Copy link
Copy Markdown
Contributor

What

Reuse the already-resolved segment indices in resolveSegmentRange() instead of calling sourceOffsetAt() (which re-does the same binary search via findSegmentAt()).

Why

A non-empty range query performed 4 x O(log segments) binary searches:

  1. findSegmentIndexAt(segments, valueStart) — kept
  2. findSegmentIndexAt(segments, valueEnd - 1) — kept
  3. sourceOffsetAt() -> findSegmentAt(segments, valueStart) — removed
  4. sourceOffsetAt() -> findSegmentAt(segments, valueEnd - 1) — removed

Steps 3-4 are now inlined using the already-resolved indices from steps 1-2.

Changes

  • resolveSegmentRange(): inline offset calculation from the resolved segment indices; remove valueLength from destructuring (no longer needed).
  • sourceOffsetAt(): removed (zero callers after inline).
  • bench-source-map.mjs: add random range queries (10k random range queries per size), rename random queries to random single-unit queries, increase query full value range from 1k to 10k iterations, switch query patterns from time() to timeMedian() for stable A/B comparison.

Benchmark (A/B, 3-sample median)

random single-unit queries          baseline (4x)  optimized (2x)  speedup
1 KiB                                    0.10 ms       0.10 ms        —
16 KiB                                   2.51 ms       0.89 ms       ~65%
64 KiB                                   8.29 ms       4.65 ms       ~44%
256 KiB                                 43.45 ms      30.18 ms       ~31%

random range queries (10k iterations)    baseline (4x)  optimized (2x)  speedup
1 KiB                                    2.97 ms       1.94 ms       ~35%
16 KiB                                   4.55 ms       2.25 ms       ~51%
64 KiB                                   4.29 ms       4.18 ms        ~3%
256 KiB                                  6.23 ms       4.58 ms       ~26%

query full value range (10k iterations)  baseline (4x)  optimized (2x)  speedup
16 KiB                                   1.41 ms       0.89 ms       ~37%
64 KiB                                   1.98 ms       0.92 ms       ~54%
256 KiB                                  1.39 ms       1.08 ms       ~22%

random single-unit queries consistently shows 31-65% speedup across sizes. random range queries is noisier because the optimization only eliminates the second pair of searches — the first pair (already present before) dominates the variance.

Verification

  • 1961/1961 tests pass
  • Bundle: 186.0 kb (down from 186.1 kb — dead code removal)

@luojiyin1987
luojiyin1987 force-pushed the perf/reuse-resolved-segments branch 2 times, most recently from 282b859 to bd70520 Compare September 7, 2026 03:29
resolveSegmentRange() already binary-searches for start and end segment
indices, then calls sourceOffsetAt() which re-does the same search via
findSegmentAt(). Inline the offset calculation to drop 2 redundant binary
searches per range query. Remove the now-dead sourceOffsetAt() function.
@luojiyin1987
luojiyin1987 force-pushed the perf/reuse-resolved-segments branch from bd70520 to 0ff0da0 Compare September 7, 2026 03:34
@luojiyin1987
luojiyin1987 merged commit b7816b5 into master Sep 7, 2026
14 checks passed
@luojiyin1987
luojiyin1987 deleted the perf/reuse-resolved-segments branch September 7, 2026 03:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant