Skip to content

perf: store single source-map segments directly - #116

Closed
luojiyin1987 wants to merge 1 commit into
masterfrom
perf/single-segment-storage
Closed

luojiyin1987 wants to merge 1 commit into
masterfrom
perf/single-segment-storage

Conversation

@luojiyin1987

@luojiyin1987 luojiyin1987 commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Store one source-map segment without an array.
  • Promote the mapping when a second segment arrives.
  • Apply the storage form to text, code, inline code, and URL mappings.
  • Accept the npm-style separator in the heap profiler.

Memory result

The many-nodes raw profile removes 10,000 arrays.
It also removes 10,000 backing stores.
Retained memory decreases by 1,840,000 bytes, or about 1.75 MiB.
The heap snapshot file decreases from 32.8 MiB to 31.8 MiB.

Same-machine A/B benchmark

Base is 1fd0f0f. Head is 5508c40.
Both revisions use the same machine, Node version, dependencies, and esbuild binary.
The test ran five alternating rounds in AB, BA, AB, BA, AB order.
The existing harness warmed each case and used three samples per round.
The table reports the median across the five rounds.

Query pattern Base median Head median Change
random range queries 5.32 ms 4.94 ms -7.1%
random single-unit queries 27.39 ms 28.56 ms +4.3%
query every code unit 10.96 ms 11.59 ms +5.7%
sequential span queries 1.91 ms 1.98 ms +3.7%

The CI signal of about 20% did not reproduce on the same machine.
No query pattern shows a stable regression of 10% or more.
The result does not require a multi-segment fast-path change.

Validation

  • pnpm run lint
  • pnpm test
  • 23 test suites passed.
  • 1,964 tests passed.

Store one segment directly in each mapping.

Promote the mapping when a second segment arrives.

The many-nodes profile removes 10,000 arrays and 10,000 backing stores.

This reduces retained memory by 1.75 MiB.
@luojiyin1987

Copy link
Copy Markdown
Contributor Author

Closing this after reviewing the trade-off.

The heap reduction is measurable (~1.75 MiB for the many-nodes fixture), but the Segment | Segment[] representation adds permanent complexity to the source-map core and slightly complicates the query path.

The profiling work was still useful: it shows that the remaining memory cost is largely structural rather than low-risk allocation waste. I don't think the measured saving justifies the additional representation complexity without evidence of a real workload where this is a bottleneck.

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