Skip to content

perf: introduce ModuleGraphCache and cache the result of get_mode and determine_export_assignments #10584

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 18 commits into
base: main
Choose a base branch
from

Conversation

CPunisher
Copy link
Collaborator

@CPunisher CPunisher commented Jun 5, 2025

Summary

Related: web-infra-dev/rslib#1011

In my M3Pro:

Benchmark: Default Before After
rslib 993ms 260ms
unbuild - 639ms
tsup - 71ms
tsdown - 41ms

Most changed files are due to the trait method signature changes and passing module_graph_cache, you may only need to focus on the following files:

  • crates/rspack_core/src/compiler/compilation.rs
  • crates/rspack_core/src/artifacts/module_graph_cache_artifact.rs
  • crates/rspack_plugin_javascript/src/dependency/esm/esm_export_imported_specifier_dependency.rs
  • ... search freeze()

Compare with Webpack

  1. Webpack cache the results of getMode with dependencyCacheProvide(https://github.com/webpack/webpack/blob/19ca74127f7668aaf60d59f4af8fcaee7924541a/lib/ModuleGraph.js#L829). But it seems that rspack doesn't port the moduleMemCache. I'm not sure this is a further optimization or a fallback for correctness.
  2. Keys for caching DetermineExportAssginments are different, see the comments https://github.com/web-infra-dev/rspack/pull/10584/files#diff-24cb30e171ddb52a6fa8ee0070a832ad5164167b770ffd8c3b8def27cd3becd2R112

To validate the cache effectiveness, I collect the cache stats:

total unfreezed cache miss cache hit
GetMode - Rspack 12000 2000 4000 6000
GetMode - Webpack 14000 2000 6000 6000
DetermineExportAssignments - Rspack 6993 1998 4 4991
DetermineExportAssignments - Webpack 6993 1998 4 4991

Not sure why webpack execute GetMode for 2000 times more than rspack

Further

There are still improvements to do, but I'd like to finish them in separated prs

  1. Incremental cache. Currently both webpack and rspack invalidate all the module graph cache when necessary. But I believe some cache is reusable.
  2. Optimize ExportsMode. From my observation ExportsMode can split to variants to reduce the struct size, thus making it cheaper to clone from the cache.

Checklist

  • Tests updated (or not required).
  • Documentation updated (or not required).

Copy link

netlify bot commented Jun 5, 2025

Deploy Preview for rspack canceled.

Built without sensitive environment variables

Name Link
🔨 Latest commit 91c0fc2
🔍 Latest deploy log https://app.netlify.com/projects/rspack/deploys/6846aa28af2a9400086947cf

@github-actions github-actions bot added the release: performance release: performance related release(mr only) label Jun 5, 2025

This comment was marked as outdated.

@CPunisher CPunisher force-pushed the 06-04-perf/cache-get-mode branch from 5ac555b to f075ac8 Compare June 9, 2025 02:27
Copy link

codspeed-hq bot commented Jun 9, 2025

CodSpeed Performance Report

Merging #10584 will not alter performance

Comparing CPunisher:06-04-perf/cache-get-mode (91c0fc2) with main (d15504a)

🎉 Hooray! codspeed-node just leveled up to 4.0.1!

A heads-up, this is a breaking change and it might affect your current performance baseline a bit. But here's the exciting part - it's packed with new, cool features and promises improved result stability 🥳!
Curious about what's new? Visit our releases page to delve into all the awesome details about this new version.

Summary

✅ 12 untouched benchmarks

@CPunisher CPunisher force-pushed the 06-04-perf/cache-get-mode branch from cb31605 to ab3aab4 Compare June 9, 2025 06:59
@CPunisher CPunisher force-pushed the 06-04-perf/cache-get-mode branch from ab3aab4 to b879b9d Compare June 9, 2025 07:20
@CPunisher CPunisher marked this pull request as ready for review June 9, 2025 07:23
Copy link
Contributor

github-actions bot commented Jun 9, 2025

📝 Benchmark detail: Open

Name Base (2025-06-09 15abf21) Current Change
10000_big_production-mode_disable-minimize + exec 35.4 s ± 786 ms 35.4 s ± 216 ms +0.03 %
10000_development-mode + exec 1.87 s ± 28 ms 1.81 s ± 17 ms -3.41 %
10000_development-mode_hmr + exec 755 ms ± 26 ms 754 ms ± 27 ms -0.13 %
10000_production-mode + exec 2.27 s ± 25 ms 2.25 s ± 17 ms -1.28 %
10000_production-mode_persistent-cold + exec 2.45 s ± 33 ms 2.42 s ± 138 ms -1.29 %
10000_production-mode_persistent-hot + exec 1.73 s ± 47 ms 1.7 s ± 27 ms -2.17 %
arco-pro_development-mode + exec 1.82 s ± 98 ms 1.8 s ± 151 ms -0.79 %
arco-pro_development-mode_hmr + exec 385 ms ± 1.2 ms 385 ms ± 0.71 ms -0.14 %
arco-pro_production-mode + exec 3.38 s ± 93 ms 3.36 s ± 316 ms -0.64 %
arco-pro_production-mode_generate-package-json-webpack-plugin + exec 3.48 s ± 110 ms 3.4 s ± 52 ms -2.07 %
arco-pro_production-mode_persistent-cold + exec 3.52 s ± 226 ms 3.38 s ± 94 ms -4.00 %
arco-pro_production-mode_persistent-hot + exec 2.06 s ± 86 ms 2.02 s ± 26 ms -1.67 %
arco-pro_production-mode_traverse-chunk-modules + exec 3.43 s ± 110 ms 3.39 s ± 108 ms -1.27 %
large-dyn-imports_development-mode + exec 2.11 s ± 41 ms 2.07 s ± 139 ms -2.23 %
large-dyn-imports_production-mode + exec 2.09 s ± 40 ms 2.06 s ± 43 ms -1.30 %
threejs_development-mode_10x + exec 1.5 s ± 97 ms 1.46 s ± 32 ms -2.43 %
threejs_development-mode_10x_hmr + exec 860 ms ± 22 ms 848 ms ± 9.1 ms -1.33 %
threejs_production-mode_10x + exec 4.8 s ± 91 ms 4.84 s ± 248 ms +0.95 %
threejs_production-mode_10x_persistent-cold + exec 4.9 s ± 57 ms 4.95 s ± 294 ms +1.09 %
threejs_production-mode_10x_persistent-hot + exec 4.26 s ± 96 ms 4.26 s ± 259 ms -0.04 %
10000_big_production-mode_disable-minimize + rss memory 9548 MiB ± 746 MiB 9147 MiB ± 51.6 MiB -4.21 %
10000_development-mode + rss memory 653 MiB ± 23.9 MiB 693 MiB ± 55 MiB +6.17 %
10000_development-mode_hmr + rss memory 794 MiB ± 13.2 MiB 807 MiB ± 34.4 MiB +1.58 %
10000_production-mode + rss memory 664 MiB ± 43.2 MiB 700 MiB ± 34.7 MiB +5.43 %
10000_production-mode_persistent-cold + rss memory 760 MiB ± 52.7 MiB 816 MiB ± 37.3 MiB +7.42 %
10000_production-mode_persistent-hot + rss memory 781 MiB ± 19.2 MiB 773 MiB ± 37.3 MiB -1.08 %
arco-pro_development-mode + rss memory 576 MiB ± 58.4 MiB 591 MiB ± 43.4 MiB +2.64 %
arco-pro_development-mode_hmr + rss memory 494 MiB ± 44.3 MiB 519 MiB ± 43.4 MiB +5.03 %
arco-pro_production-mode + rss memory 695 MiB ± 40.7 MiB 725 MiB ± 93.9 MiB +4.35 %
arco-pro_production-mode_generate-package-json-webpack-plugin + rss memory 698 MiB ± 60.3 MiB 706 MiB ± 77.6 MiB +1.21 %
arco-pro_production-mode_persistent-cold + rss memory 777 MiB ± 138 MiB 821 MiB ± 76.4 MiB +5.70 %
arco-pro_production-mode_persistent-hot + rss memory 664 MiB ± 74.7 MiB 670 MiB ± 50 MiB +0.87 %
arco-pro_production-mode_traverse-chunk-modules + rss memory 697 MiB ± 90.5 MiB 700 MiB ± 69.2 MiB +0.47 %
large-dyn-imports_development-mode + rss memory 661 MiB ± 6.44 MiB 687 MiB ± 14.9 MiB +3.88 %
large-dyn-imports_production-mode + rss memory 555 MiB ± 8.09 MiB 579 MiB ± 13.3 MiB +4.44 %
threejs_development-mode_10x + rss memory 624 MiB ± 9.86 MiB 656 MiB ± 18.4 MiB +5.08 %
threejs_development-mode_10x_hmr + rss memory 815 MiB ± 25.4 MiB 846 MiB ± 24.8 MiB +3.84 %
threejs_production-mode_10x + rss memory 878 MiB ± 32.1 MiB 927 MiB ± 27.1 MiB +5.56 %
threejs_production-mode_10x_persistent-cold + rss memory 992 MiB ± 27.4 MiB 1014 MiB ± 49.4 MiB +2.28 %
threejs_production-mode_10x_persistent-hot + rss memory 837 MiB ± 42.5 MiB 842 MiB ± 52.6 MiB +0.59 %

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release: performance release: performance related release(mr only)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant