-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Add "Optimizing Build Performance" section to the Cargo book #15924
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
Merged
+72
−0
Merged
Changes from 1 commit
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
7b6d35f
Add "Optimizing Build Performance" section to the Cargo book
Kobzol 79f56d5
Fix typo
Kobzol 5940262
Reword with focus on trade-offs
Kobzol 97ec21d
Add configuration changes section
Kobzol df7e02d
Split text into two sections
Kobzol 5c1631c
Reword intro, remove nightly/unstable feature sub-headings, clarify C…
Kobzol File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# Optimizing Build Performance | ||
|
||
Compilation of Rust crates can sometimes be rather slow, due to various reasons (such as the used compilation model and the design of the Rust language and its compiler). There are various approaches that can be used to optimize build performance, which mostly fall under two categories: | ||
|
||
- Modify compiler or Cargo flags | ||
- Modify the source code of your crate(s) | ||
|
||
This guide focuses on the first approach. | ||
|
||
Below, you can find several methods that can be used to optimize build performance. It is important to nore that their effect varies a lot based on the compiled crate, and in some cases they can actually make compilation slower. You should always measure build performance on your crate(s) to determine if a given method described here is effective for your crate. | ||
Kobzol marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
epage marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
Note that some of these approaches currently require using the nightly toolchain. | ||
|
||
## Reduce amount of generated debug information | ||
Kobzol marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
Kobzol marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
By default, the `dev` [profile](../reference/profiles.md) enables generation of full debug information (debuginfo) both for local crates and also for all dependencies. This is useful if you want to debug your code with a debugger or profile it with a profiler, but it can also have a significant compilation and linking time cost. | ||
|
||
You can reduce that cost by reducing the amount of debuginfo that is generated. The fastest option is `debug = false`, which completely turns off debuginfo generation, but a reasonable trade-off could also be setting `debug = "line-tables-only"`, which only generates enough debuginfo to support proper source code links in backtraces, which are generated e.g. when a panic happens. | ||
|
||
Here is an example of configuring debuginfo generation in `Cargo.toml`: | ||
```toml | ||
[profile.dev] | ||
debug = false # or "line-tables-only" | ||
``` | ||
|
||
If you want to keep debuginfo for your crate only, but you do not need it for your dependencies, you can set `debug = false` as the default value for a given profile, and then enable debuginfo only for your crate: | ||
|
||
```toml | ||
[profile.dev] | ||
debug = false | ||
|
||
[profile.dev.package] | ||
<your-crate-name>.debug = true | ||
``` | ||
|
||
## Use an alternative codegen backend | ||
|
||
> **This requires nightly/unstable features** | ||
|
||
The component of the Rust compiler that generates executable code is called a "codegen backend". The default backend is LLVM, which produces very optimized code, at the cost of relatively slow compilation time. You can try to use a different codegen backend in order to speed up the compilation of your crate. | ||
|
||
You can use the [Cranelift](https://github.com/rust-lang/rustc_codegen_cranelift) backend, which is designed for fast(er) compilation time. You can install this backend using rustup: | ||
|
||
```console | ||
$ rustup component add rustc-codegen-cranelift-preview --toolchain nightly | ||
``` | ||
|
||
and then enable it for a given Cargo profile using the `codegen-backend` option in `Cargo.toml`: | ||
```toml | ||
[profile.dev] | ||
codegen-backend = "cranelift" | ||
``` | ||
|
||
Since this is currently an unstable option, you will also need to either pass `-Z codegen-backend` to Cargo, or enable this unstable option in the `.cargo/config.toml` file. You can find more information about the unstable `codegen-backend` profile option [here](../reference/unstable.md#codegen-backend). | ||
Kobzol marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
Note that the Cranelift backend might not support all features used by your crate. It is also available only for a limited set of targets. | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have some "tips" at https://doc.rust-lang.org/nightly/cargo/reference/timings.html, should we switch that to a link to this page?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or maybe fold that page into this one and setup a redirect
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to include a "how to profile my builds" in this page, which could link to the timings page as one of the points. And the timings page could then cross-link here for "how to optimize build perf.".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was considering bringing up dividing this into two sections
--timings
, compiler passes, macro lines,cargo llvm-lines
)I was just split on that vs framing those in terms of the current organization. For example, we could have a section on reducing the impact of generics and talk through using
cargo llvm-lines
to find large, repeated generic functions and discuss how to improve that.