Skip to content
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

perf(turbo-tasks): Filter out and do not cache unused arguments #75261

Merged
merged 3 commits into from
Jan 29, 2025

Conversation

bgw
Copy link
Member

@bgw bgw commented Jan 24, 2025

For trait methods, we often have underscore-prefixed arguments that are unused in method implementations, but must exist on the method signature because the trait requires it.

For example, look at code_generation: https://github.com/search?q=repo%3Avercel%2Fnext.js%20fn%20code_generation&type=code

We can filter those arguments as soon as we resolve the real method, and avoid storing them as part of the task's cache key.

This should mean less data stored per task, and better cache hit rates (so less tasks overall).

This appears to give a roughly 5% memory win:

Screenshot 2025-01-28 at 11.54.37 AM.png

(Spreadsheet: https://docs.google.com/spreadsheets/d/1fz9Q-tDE6LebS9p4Mci8vZG7jkBSajiMYF1WbZEPnts/edit?usp=sharing)

Full data:

Tested with next-site in front.

Command run:

rm -rf .next && TURBOPACK=1 TURBOPACK_BUILD=1 TURBO_ENGINE_READ_ONLY=1 /bin/time -v pnpm next build --experimental-build-mode=compile

Before, run 1

Compiled in: 19.3s

        Command being timed: "pnpm next build --experimental-build-mode=compile"
        User time (seconds): 121.88
        System time (seconds): 16.74
        Percent of CPU this job got: 501%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:27.61
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 5607868
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 58
        Minor (reclaiming a frame) page faults: 1816374
        Voluntary context switches: 1280636
        Involuntary context switches: 361414
        Swaps: 0
        File system inputs: 102088
        File system outputs: 738000
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0

Before, run 2

Compiled in: 19.3s

        Command being timed: "pnpm next build --experimental-build-mode=compile"
        User time (seconds): 124.34
        System time (seconds): 16.97
        Percent of CPU this job got: 516%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:27.36
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 5455968
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 8
        Minor (reclaiming a frame) page faults: 2014509
        Voluntary context switches: 1267794
        Involuntary context switches: 358175
        Swaps: 0
        File system inputs: 6496
        File system outputs: 737296
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0

Before, run 3

Compiled in: 18.4s

        Command being timed: "pnpm next build --experimental-build-mode=compile"
        User time (seconds): 117.81
        System time (seconds): 15.86
        Percent of CPU this job got: 505%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:26.46
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 5655912
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 5
        Minor (reclaiming a frame) page faults: 1868540
        Voluntary context switches: 1271444
        Involuntary context switches: 337236
        Swaps: 0
        File system inputs: 7784
        File system outputs: 737480
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status:

Before, run 4

Compiled in: 18.2s

        Command being timed: "pnpm next build --experimental-build-mode=compile"
        User time (seconds): 116.98
        System time (seconds): 15.09
        Percent of CPU this job got: 504%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:26.15
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 5962764
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 0
        Minor (reclaiming a frame) page faults: 1861147
        Voluntary context switches: 1253759
        Involuntary context switches: 333116
        Swaps: 0
        File system inputs: 0
        File system outputs: 737304
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0

Before, run 5

Compiled in: 17.9s

        Command being timed: "pnpm next build --experimental-build-mode=compile"
        User time (seconds): 119.02
        System time (seconds): 14.84
        Percent of CPU this job got: 516%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:25.92
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 5745780
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 0
        Minor (reclaiming a frame) page faults: 1542655
        Voluntary context switches: 1238600
        Involuntary context switches: 357049
        Swaps: 0
        File system inputs: 0
        File system outputs: 737000
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0

After, run 1

Compiled in: 19.0s

        Command being timed: "pnpm next build --experimental-build-mode=compile"
        User time (seconds): 121.85
        System time (seconds): 16.69
        Percent of CPU this job got: 508%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:27.22
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 5402708
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 41
        Minor (reclaiming a frame) page faults: 1822829
        Voluntary context switches: 1221091
        Involuntary context switches: 361604
        Swaps: 0
        File system inputs: 110200
        File system outputs: 737048
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0

After, run 2

Compiled in: 18.5s

        Command being timed: "pnpm next build --experimental-build-mode=compile"
        User time (seconds): 119.46
        System time (seconds): 15.32
        Percent of CPU this job got: 506%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:26.60
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 5413980
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 1
        Minor (reclaiming a frame) page faults: 1695775
        Voluntary context switches: 1269774
        Involuntary context switches: 328448
        Swaps: 0
        File system inputs: 800
        File system outputs: 736952
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0

After, run 3

Compiled in: 18.5s

        Command being timed: "pnpm next build --experimental-build-mode=compile"
        User time (seconds): 118.15
        System time (seconds): 15.12
        Percent of CPU this job got: 503%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:26.48
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 5312528
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 0
        Minor (reclaiming a frame) page faults: 1893778
        Voluntary context switches: 1277325
        Involuntary context switches: 324591
        Swaps: 0
        File system inputs: 128
        File system outputs: 737304
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0

After, run 4

Compiled in: 18.2s

        Command being timed: "pnpm next build --experimental-build-mode=compile"
        User time (seconds): 115.60
        System time (seconds): 15.30
        Percent of CPU this job got: 499%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:26.22
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 5240892
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 1
        Minor (reclaiming a frame) page faults: 1514837
        Voluntary context switches: 1296049
        Involuntary context switches: 312076
        Swaps: 0
        File system inputs: 32
        File system outputs: 737664
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0

After, run 5

Compiled in: 19.4s

        Command being timed: "pnpm next build --experimental-build-mode=compile"
        User time (seconds): 125.91
        System time (seconds): 15.63
        Percent of CPU this job got: 514%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:27.50
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 5346672
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 1
        Minor (reclaiming a frame) page faults: 1839175
        Voluntary context switches: 1280293
        Involuntary context switches: 358863
        Swaps: 0
        File system inputs: 32
        File system outputs: 737720
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0

Closes PACK-3833

@ijjk
Copy link
Member

ijjk commented Jan 24, 2025

Tests Passed

@bgw bgw marked this pull request as ready for review January 24, 2025 15:26
@bgw bgw marked this pull request as draft January 24, 2025 15:26
@bgw bgw force-pushed the bgw/fn-local-option branch from a7429b6 to 40fd0db Compare January 24, 2025 16:30
@bgw bgw force-pushed the bgw/filter-unused-args branch from 4dcf00f to f22bdcd Compare January 24, 2025 16:30
@ijjk
Copy link
Member

ijjk commented Jan 24, 2025

Stats from current PR

Default Build (Increase detected ⚠️)
General
vercel/next.js canary vercel/next.js bgw/filter-unused-args Change
buildDuration 19.2s 16.6s N/A
buildDurationCached 15.7s 13s N/A
nodeModulesSize 392 MB 392 MB
nextStartRea..uration (ms) 442ms 441ms N/A
Client Bundles (main, webpack)
vercel/next.js canary vercel/next.js bgw/filter-unused-args Change
5306-HASH.js gzip 54 kB 53.9 kB N/A
8276.HASH.js gzip 169 B 168 B N/A
8377-HASH.js gzip 5.46 kB 5.46 kB N/A
bccd1874-HASH.js gzip 52.9 kB 52.9 kB
framework-HASH.js gzip 57.5 kB 57.5 kB N/A
main-app-HASH.js gzip 241 B 242 B N/A
main-HASH.js gzip 34.5 kB 34.4 kB N/A
webpack-HASH.js gzip 1.71 kB 1.71 kB N/A
Overall change 52.9 kB 52.9 kB
Legacy Client Bundles (polyfills)
vercel/next.js canary vercel/next.js bgw/filter-unused-args Change
polyfills-HASH.js gzip 39.4 kB 39.4 kB
Overall change 39.4 kB 39.4 kB
Client Pages
vercel/next.js canary vercel/next.js bgw/filter-unused-args Change
_app-HASH.js gzip 193 B 193 B
_error-HASH.js gzip 193 B 193 B
amp-HASH.js gzip 512 B 510 B N/A
css-HASH.js gzip 343 B 342 B N/A
dynamic-HASH.js gzip 1.84 kB 1.84 kB
edge-ssr-HASH.js gzip 265 B 265 B
head-HASH.js gzip 363 B 362 B N/A
hooks-HASH.js gzip 393 B 392 B N/A
image-HASH.js gzip 4.59 kB 4.58 kB N/A
index-HASH.js gzip 268 B 268 B
link-HASH.js gzip 2.35 kB 2.35 kB N/A
routerDirect..HASH.js gzip 328 B 328 B
script-HASH.js gzip 397 B 397 B
withRouter-HASH.js gzip 323 B 326 B N/A
1afbb74e6ecf..834.css gzip 106 B 106 B
Overall change 3.59 kB 3.59 kB
Client Build Manifests
vercel/next.js canary vercel/next.js bgw/filter-unused-args Change
_buildManifest.js gzip 748 B 747 B N/A
Overall change 0 B 0 B
Rendered Page Sizes
vercel/next.js canary vercel/next.js bgw/filter-unused-args Change
index.html gzip 524 B 523 B N/A
link.html gzip 539 B 537 B N/A
withRouter.html gzip 520 B 520 B
Overall change 520 B 520 B
Edge SSR bundle Size
vercel/next.js canary vercel/next.js bgw/filter-unused-args Change
edge-ssr.js gzip 129 kB 129 kB N/A
page.js gzip 210 kB 210 kB N/A
Overall change 0 B 0 B
Middleware size
vercel/next.js canary vercel/next.js bgw/filter-unused-args Change
middleware-b..fest.js gzip 669 B 665 B N/A
middleware-r..fest.js gzip 155 B 156 B N/A
middleware.js gzip 31.3 kB 31.3 kB N/A
edge-runtime..pack.js gzip 844 B 844 B
Overall change 844 B 844 B
Next Runtimes
vercel/next.js canary vercel/next.js bgw/filter-unused-args Change
app-page-exp...dev.js gzip 386 kB 386 kB N/A
app-page-exp..prod.js gzip 131 kB 131 kB
app-page-tur..prod.js gzip 144 kB 144 kB
app-page-tur..prod.js gzip 140 kB 140 kB
app-page.run...dev.js gzip 373 kB 373 kB N/A
app-page.run..prod.js gzip 128 kB 128 kB
app-route-ex...dev.js gzip 39.4 kB 39.4 kB
app-route-ex..prod.js gzip 25 kB 25 kB
app-route-tu..prod.js gzip 25 kB 25 kB
app-route-tu..prod.js gzip 24.8 kB 24.8 kB
app-route.ru...dev.js gzip 41 kB 41 kB
app-route.ru..prod.js gzip 24.8 kB 24.8 kB
dist_client_...dev.js gzip 326 B 326 B
dist_client_...dev.js gzip 318 B 318 B
pages-api-tu..prod.js gzip 8.81 kB 8.81 kB
pages-api.ru...dev.js gzip 11.5 kB 11.5 kB
pages-api.ru..prod.js gzip 8.8 kB 8.8 kB
pages-turbo...prod.js gzip 21.6 kB 21.6 kB
pages.runtim...dev.js gzip 31.3 kB 31.3 kB N/A
pages.runtim..prod.js gzip 21.6 kB 21.6 kB
server.runti..prod.js gzip 73.7 kB 73.7 kB
Overall change 870 kB 870 kB
build cache Overall increase ⚠️
vercel/next.js canary vercel/next.js bgw/filter-unused-args Change
0.pack gzip 2.1 MB 2.1 MB ⚠️ +1.89 kB
index.pack gzip 75.6 kB 75.6 kB N/A
Overall change 2.1 MB 2.1 MB ⚠️ +1.89 kB
Diff details
Diff for main-HASH.js

Diff too large to display

Diff for app-page-exp..ntime.dev.js
failed to diff
Diff for app-page.runtime.dev.js
failed to diff
Diff for pages.runtime.dev.js

Diff too large to display

Commit: 100c6a7

@bgw bgw force-pushed the bgw/fn-local-option branch from 40fd0db to 2a987b0 Compare January 24, 2025 17:46
@bgw bgw force-pushed the bgw/filter-unused-args branch from f22bdcd to 28e47be Compare January 24, 2025 17:46
@bgw bgw force-pushed the bgw/fn-local-option branch from 2a987b0 to dd12daa Compare January 24, 2025 18:33
@bgw bgw force-pushed the bgw/filter-unused-args branch from 28e47be to 25ef396 Compare January 24, 2025 18:34
@bgw bgw force-pushed the bgw/fn-local-option branch 2 times, most recently from 51a826a to 35fc3ed Compare January 24, 2025 19:18
@bgw bgw force-pushed the bgw/filter-unused-args branch from 25ef396 to c8519e8 Compare January 24, 2025 19:18
@bgw bgw force-pushed the bgw/fn-local-option branch from 35fc3ed to 0151e49 Compare January 24, 2025 19:24
@bgw bgw force-pushed the bgw/filter-unused-args branch from c8519e8 to 5c57296 Compare January 24, 2025 19:24
@bgw bgw force-pushed the bgw/fn-local-option branch from 0151e49 to 0c17996 Compare January 24, 2025 22:05
@bgw bgw changed the base branch from bgw/fn-local-option to graphite-base/75261 January 24, 2025 22:29
@bgw bgw force-pushed the bgw/filter-unused-args branch from 5c57296 to 3e43193 Compare January 24, 2025 22:31
@bgw bgw force-pushed the graphite-base/75261 branch from 0c17996 to 7578b8f Compare January 24, 2025 22:31
@bgw bgw changed the base branch from graphite-base/75261 to canary January 24, 2025 22:31
@bgw bgw force-pushed the bgw/filter-unused-args branch 3 times, most recently from 46bad4f to f1e477b Compare January 28, 2025 19:34
@bgw bgw requested review from mischnic, sokra and kdy1 January 28, 2025 19:59
@bgw bgw marked this pull request as ready for review January 28, 2025 19:59
Copy link
Member

@sokra sokra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of the turbo-tasks test cases use _key arguments to make unqiue tasks. Maybe we need to update them to use let _ = arg;

@bgw bgw force-pushed the bgw/filter-unused-args branch from f1e477b to 100c6a7 Compare January 28, 2025 21:19
@bgw
Copy link
Member Author

bgw commented Jan 28, 2025

Some of the turbo-tasks test cases use _key arguments to make unqiue tasks. Maybe we need to update them to use let _ = arg;

It looks like none of those cases are trait methods, and this PR only impacts trait methods, but I think we should generate a compiler error in the future on non-trait-methods/functions with unused arguments to help ensure some consistency (i.e. that underscored arguments are never used as cache keys).

Using underscored arguments on non-trait-methods/functions is likely a mistake, and there are workarounds (wrapper functions, let _ = arg) if you really need to do that.

I've fixed the cases I could find in the tests.

@bgw
Copy link
Member Author

bgw commented Jan 28, 2025

Follow up work: https://linear.app/vercel/issue/PACK-3828/argument-filtering-follow-ups

  • Add unit tests for the trait method behavior
  • Error if underscore-prefixed arguments are used on functions or non-trait methods.
  • Filter unused self arguments on all methods (hard/tricky?).
  • Add some mention of this behavior to the docs. Ideally after getting the self filtering working as well.

@bgw bgw requested a review from sokra January 29, 2025 17:22
Copy link
Member

@sokra sokra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A test case would be great

Copy link
Member Author

bgw commented Jan 29, 2025

A test case would be great

I will do this in a follow up. I'm pretty confident nothing's broken by this, but there's some risk we could silently break this optimization without a unit test.

@bgw bgw merged commit 8ed8716 into canary Jan 29, 2025
131 checks passed
@bgw bgw deleted the bgw/filter-unused-args branch January 29, 2025 21:51
bgw added a commit that referenced this pull request Feb 3, 2025
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 26, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
created-by: Turbopack team PRs by the Turbopack team. locked
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants