Avatar for the swc-project user
swc-project
swc
BlogDocsChangelog

Performance History

Latest Results

perf(bindings): 8–10% smaller addons, 11–12% less decode time, 29.4 MB less compression-table memory (#12740) **Description:** <!-- native-decoding:start --> [This implementation](https://github.com/jdalton/swc/compare/c8d37f173207e7f8d7e2bc029a10d9babe95ed44...0a101c7041509ce3290f2cb8dba659c4c1ae03d1) makes the measured Darwin ARM64 addon files **8.27% smaller for SWC (0.74 MB saved)** and **9.92% smaller for Rspack (1.29 MB saved)**, with **11.70% and 10.59% less verified decoding time**. Peak decoding-benchmark memory falls **3.46% and 9.76%**, respectively. The compression lookup table also uses **4.2 MB instead of 33.6 MB: 29.4 MB less allocation** against the large-table control described below. ### Historical combined measurement: before feature gating **Historical measurements:** these results predate filesystem-feature gating and do not validate the current gated implementation. A fresh volume without compression feature bits now uses zlib. A current-revision benchmark on both baseline and explicitly zstd-enabled volumes remains outstanding. On the same Linux ARM64/Btrfs setup, this PR’s optimized native payload plus #12739’s zstd replacement produced **a 12.3% smaller complete carrier, 23.5% faster first native `require()`, 65.0% faster follow-up cold `require()`, and 1.7% less Btrfs allocated space** versus the baseline with neither change. The two standalone percentages are not added; these figures are a direct measurement of both changes together. ![Combined benchmark: 12.3% smaller carrier, 23.5% faster first require, 65.0% faster follow-up require, and 1.7% less Btrfs allocated space.](https://github.com/user-attachments/assets/f81189f2-dadb-40dd-9ba6-bbaefc3320ad) | Metric | Baseline | Both changes | Improvement | | --- | ---: | ---: | ---: | | Complete carrier | 10.7 MB | 9.4 MB | 12.3% smaller | | Btrfs allocated space after replacement | 14.2 MB | 14.0 MB | 1.7% less | | First carrier `require()` | 284.6 ms | 217.7 ms | 23.5% faster | | Follow-up cold `require()` | 61.8 ms | 21.6 ms | 65.0% faster | The run used eight alternating trials per build and three follow-up loads per trial. Each first load verified that the carrier was replaced with the original addon. Full method and raw measurements: [combined benchmark artifacts](https://github.com/jdalton/swc/tree/3b2fe574d7a86f88129f96566fb8bcbb93e19ee0/benchmark-artifacts/combined-native-btrfs). This is one Linux ARM64 VM; file page cache was evicted, but other VM/host caches were uncontrolled. <!-- combined-native-btrfs-result --> ![Complete addon files are smaller, verified decoding takes less time, and peak benchmark memory is lower for both SWC and Rspack.](https://github.com/user-attachments/assets/03d432f7-b128-48d5-87fb-abd182dace67) <details> <summary>Measured results and benchmark method</summary> The baseline uses original level-16 compression and streaming decoding. The final implementation uses tuned level-22 compression, bounded bulk decoding, and batched writes. A complete `.node` file includes both the compressed addon and its loader. MB uses decimal units. | Metric | SWC 1.16.2: baseline → final | Rspack 1.7.0: baseline → final | | --- | ---: | ---: | | Complete `.node` file | 8.989 → 8.246 MB (−8.27%) | 12.985 → 11.697 MB (−9.92%) | | Verified decoding elapsed time | 50.876 → 44.926 ms (−11.70%) | 76.506 → 68.401 ms (−10.59%) | | Peak benchmark process memory | 46.0 → 44.4 MB (−3.46%) | 72.2 → 65.2 MB (−9.76%) | The final implementation was faster in all five paired process comparisons for both inputs. The smaller table plus batched writes also beat the Hash21 bulk-decoding control by 7.06% for SWC and 7.99% for Rspack, again in all five pairs. Each variant/input ran in five fresh processes with balanced ordering, two warmups, and twelve measured rounds per process. Reported runtime values are medians of process medians. Timed work includes decompression, full-content BLAKE3 verification, and staging-file writes. Independent SHA-512 checks outside timing verified all 420 outputs in the final three-variant confirmation. Peak memory includes process setup and independent verification. Measurements used a plugged-in Apple M1 Max on Darwin ARM64, with benchmark jobs serialized and file indexers temporarily suspended. Other system work remained active; host snapshots are included. Scope is built addon-file size and staging-file decoding. Full addon startup, npm transfer size, and other-platform performance remain unmeasured. </details> <!-- native-decoding:end --> <!-- native-packing:start --> <details> <summary>Compression memory savings and build-time CPU tradeoff</summary> The lookup table helps the compressor find repeated data. Its allocation falls from **33.6 MB to 4.2 MB**, saving **29.4 MB (87.5%)**, when comparing the `HashLog(23)` large-table control with `HashLog(20)`. This is table allocation, not total process memory; Hash23 is not zstd's default. ![The compression lookup table decreases from 33.6 MB to 4.2 MB, with a separate measured packing-memory and CPU comparison.](https://github.com/user-attachments/assets/30c9ed23-c6a6-49d8-b87f-a73d16fdb6b7) A separate three-pair comparison of Hash21 against Hash20 measured **4.2 MB less peak packing-benchmark memory on both inputs**: | Packing benchmark | Hash21 control → Hash20 final | | --- | ---: | | SWC peak process memory | 358.0 → 353.8 MB | | Rspack peak process memory | 674.5 → 670.3 MB | | SWC process CPU time | 8.56 → 9.33 s (+9.00%) | | Rspack process CPU time | 15.35 → 16.12 s (+5.02%) | These fresh-process measurements include compression and exact round-trip verification, with the compressor retained. They are distinct from production-packer RSS and runtime memory. The smaller table trades more build-time CPU for lower allocation; no compression-speed improvement is claimed. Final compressed payloads are 7.698436 MB for SWC and 11.133901 MB for Rspack. The production packer reproduced the measured frames exactly. Complete-file measurements above include loader overhead and padding. </details> <!-- native-packing:end --> <details> <summary>Implementation, correctness, and reproduction</summary> - Inputs of at least 8 MiB use level 22, long-distance matching, `HashLog(20)`, and `SearchLog(8)`. Smaller inputs retain level 16; compression windows remain capped at 64 MiB. - Images up to 64 MiB whose frame history covers the full output reuse the decoded buffer as history. Other frames retain streaming. Writes are grouped directly from that buffer, preserving hashing chunks and adding no extra buffer or copying. - Payload format, full-content integrity, window/length/target checks, cache security, and atomic publication are preserved. No decmpfs dependency is added. - **40 crate tests passed; three platform-specific tests were skipped.** Formatting and focused Clippy passed. Fixtures cover single-segment, explicit-window, and legacy frames; both hash modes and corruption; output-write failures; and the 64 MiB boundary. - Both complete `.node` files built successfully and contained the exact verified payloads. The combined table/write change adds no complete-file size beyond the bulk decoder. The bulk decoder adds 0.0165 MB to the SWC `.node` file compared with the same payload and streaming decoder; the overall size reductions above already include that cost. - Validation covers the native-addon crate and built Darwin ARM64 `.node` files. Full-workspace and cross-platform checks remain outstanding. The required release changeset is included. [Raw results, input and binary hashes, source, host snapshots, validation logs, chart scripts, and reproduction instructions](https://github.com/jdalton/swc/tree/3a1861698ef6fb777cbe5e8bf0ff4d8cd5c9cdc2/benchmark-artifacts/decoding/final-0a101c704-20261109). The optional local benchmark guard suspends only explicitly selected `fff-mcp` indexers and restores them after the batch or on timeout. </details> **Related issue:** [#12741](https://github.com/swc-project/swc/issues/12741). <details> <summary>Memory scope and compression CPU tradeoff</summary> Measured peak decoding-benchmark process memory falls from **46.0 to 44.4 MB for SWC** and **72.2 to 65.2 MB for Rspack**. The separate **29.4 MB saving** is compression lookup-table allocation against the explicitly configured large-table control, not total process RAM or a comparison against zstd defaults. The smaller table uses **5–9% more packing CPU time** in the paired measurements. This is a deliberate build-time cost for lower memory; runtime decoding remains faster. No packing-speed improvement is claimed. </details> <details> <summary>Current revision and review follow-up</summary> Rebased onto upstream `main` at `96e93547e` and consolidated into one commit. Historical benchmark links above retain the exact measured revisions; the refresh has not been re-benchmarked. Both Codex documentation findings are addressed: the release guide and crate format guide describe the level-22 threshold and level-16 fallback, and the memory contract distinguishes the bounded bulk-output buffer from streaming and total process memory. Validation: 40 native crate tests passed, with three platform-specific tests ignored. Focused Clippy and formatting passed. Full-workspace Clippy and the Node development build could not complete within available local disk space; Node integration tests were therefore not run. CodSpeed’s CPU simulation report warns that syscall costs are omitted. The filesystem and decoding results above use separate wall-clock measurements and are not inferred from that CPU simulation report. </details>
main
44 minutes ago
perf(bindings): prefer zstd for btrfs native replacement
jdalton:perf/native-btrfs-codec-fallback
1 hour ago
perf(bindings): reduce native payload size and decoding overhead
jdalton:perf/native-payload-long-matches
1 hour ago
perf(bindings): prefer zstd for btrfs native replacement
jdalton:perf/native-btrfs-codec-fallback
1 hour ago
Merge branch 'main' into spread
Austaras:spread
1 hour ago
perf(bindings): prefer zstd for btrfs native replacement
jdalton:perf/native-btrfs-codec-fallback
2 hours ago
perf(bindings): reduce native payload size and decoding overhead
jdalton:perf/native-payload-long-matches
2 hours ago

Latest Branches

CodSpeed Performance Gauge
+2%
perf(bindings): prefer enabled zstd compression for Btrfs native addons#12739
2 hours ago
e14e358
jdalton:perf/native-btrfs-codec-fallback
CodSpeed Performance Gauge
+2%
perf(bindings): 8–10% smaller addons, 11–12% less decode time, 29.4 MB less compression-table memory#12740
2 hours ago
e2de9e8
jdalton:perf/native-payload-long-matches
CodSpeed Performance Gauge
+2%
1 hour ago
ffc6402
Austaras:spread
© 2026 CodSpeed Technology
Home Terms Privacy Docs