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

High overhead #6353

Open
TomFryersMidsummer opened this issue Sep 30, 2024 · 7 comments
Open

High overhead #6353

TomFryersMidsummer opened this issue Sep 30, 2024 · 7 comments

Comments

@TomFryersMidsummer
Copy link

Rustfmt has quite high per-run overhead. For example, running repeated benchmarks on my machine gives the following means:

  • echo | rustfmt: 48 ms
  • cat lib.rs | rustfmt: 55 ms

Here, lib.rs is rustfmt’s own 670-line file. 55 ms for 670 lines is pretty good! But 48 ms to format the empty string doesn’t seem quite so speedy.

Some other formatters have a much lower overhead: ruff format -, for instance, takes 4 ms. Although some are far worse: echo | prettier --parser babel takes 230 ms.

This can make quite a difference when using rustfmt in scripts. (I have a script that formats proptest function bodies, which calls rustfmt 452 times.)

@ytmimi
Copy link
Contributor

ytmimi commented Sep 30, 2024

@TomFryersMidsummer thanks fort the report. What version of rustfmt are you using? How are you calling rustfmt in your scripts? Do you have a rustfmt.toml file in the project? have you profiled rustfmt to determine where it's spending the most time?

Also, running rustfmt on lib.rs is going to format the entire project, not just the lib.rs file. You can see this if you add the -v flag to your call e.g. rustfmt -v src/lib.rs.
If you're using nightly rustfmt you can pass along the --unstable-features --skip-children flags to only format the current file.

@TomFryersMidsummer
Copy link
Author

I'm using rustfmt 1.8.0-nightly (7608018cbd 2024-09-29). I have rustfmt.toml (edition = "2021"), but running outside the project directory makes no difference.

I’m passing source code to rustfmt on standard input, but the problem is the same if I put it in a file instead. The issue arises even with no input: rustfmt --help.

I haven’t profiled Rustfmt, but I have noticed that it’s nearly twice as fast if I specify the toolchain manually, with +nightly or +stable, so perhaps toolchain selection is taking a very long time.

@TomFryersMidsummer
Copy link
Author

Better still: echo | ~/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/rustfmt is only 10 ms.

@TomFryersMidsummer
Copy link
Author

TomFryersMidsummer commented Sep 30, 2024

Largely, it looks like this is caused by this Rustup issue. But it would still be nice to be down closer to Ruff when calling the binary without the wrapper.

@ytmimi
Copy link
Contributor

ytmimi commented Sep 30, 2024

That's all very helpful info!

@calebcartwright
Copy link
Member

I’m passing source code to rustfmt on standard input, but the problem is the same if I put it in a file instead

are you making those invocations sequentially or in parallel? in the latter, are you invoking rustfmt multiple times and passing it one file each time or invoking rustfmt once and passing the full list of file paths?

I'd imagine there's some level of bootstrapping overhead each time that establishes a runtime floor, but unless there's some really straightforward low hanging fruit I don't think this is something we can really do much about, or at least I don't think we've got the spare capacity to try to optimize away a couple dozen milliseconds

@TomFryersMidsummer
Copy link
Author

TomFryersMidsummer commented Oct 11, 2024

are you making those invocations sequentially or in parallel?

In parallel.

in the latter, are you invoking rustfmt multiple times and passing it one file each time or invoking rustfmt once and passing the full list of file paths?

I'm passing it one file each time on standard input. I couldn't find a way to get Rustfmt to take more than one file on standard input. I could save everything to temporary files on tmpfs, pass this list to Rustfmt, then read them all back, but that's a bit of a silly workaround, with its own overheads. I could also concatenate them, with some special comment as a separator, and try to split them back up, but that doesn't work if a file contains syntax errors.

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

No branches or pull requests

3 participants