From 7b6d35f06a082638c49259f0a55873a5b5a319a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 4 Sep 2025 12:15:11 +0200 Subject: [PATCH 1/6] Add "Optimizing Build Performance" section to the Cargo book --- src/doc/src/SUMMARY.md | 1 + src/doc/src/guide/build-performance.md | 56 ++++++++++++++++++++++++++ src/doc/src/guide/index.md | 1 + 3 files changed, 58 insertions(+) create mode 100644 src/doc/src/guide/build-performance.md diff --git a/src/doc/src/SUMMARY.md b/src/doc/src/SUMMARY.md index d66d65f1228..40f6d4a5ed3 100644 --- a/src/doc/src/SUMMARY.md +++ b/src/doc/src/SUMMARY.md @@ -17,6 +17,7 @@ * [Continuous Integration](guide/continuous-integration.md) * [Publishing on crates.io](reference/publishing.md) * [Cargo Home](guide/cargo-home.md) + * [Optimizing Build Performance](guide/build-performance.md) * [Cargo Reference](reference/index.md) * [The Manifest Format](reference/manifest.md) diff --git a/src/doc/src/guide/build-performance.md b/src/doc/src/guide/build-performance.md new file mode 100644 index 00000000000..2852feac83a --- /dev/null +++ b/src/doc/src/guide/build-performance.md @@ -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. + +Note that some of these approaches currently require using the nightly toolchain. + +## Reduce amount of generated debug information + +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] +.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). + +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. diff --git a/src/doc/src/guide/index.md b/src/doc/src/guide/index.md index 152f666e79b..a3de59587d3 100644 --- a/src/doc/src/guide/index.md +++ b/src/doc/src/guide/index.md @@ -13,3 +13,4 @@ develop Rust packages. * [Continuous Integration](continuous-integration.md) * [Publishing on crates.io](../reference/publishing.md) * [Cargo Home](cargo-home.md) +* [Optimizing Build Performance](build-performance.md) From 79f56d54379e5b49e79e83174fc91c019bcbdf88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 4 Sep 2025 17:04:27 +0200 Subject: [PATCH 2/6] Fix typo Co-authored-by: Nicholas Nethercote --- src/doc/src/guide/build-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/src/guide/build-performance.md b/src/doc/src/guide/build-performance.md index 2852feac83a..808c05b8f4c 100644 --- a/src/doc/src/guide/build-performance.md +++ b/src/doc/src/guide/build-performance.md @@ -7,7 +7,7 @@ Compilation of Rust crates can sometimes be rather slow, due to various reasons 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. +Below, you can find several methods that can be used to optimize build performance. It is important to note 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. Note that some of these approaches currently require using the nightly toolchain. From 5940262a4a2e373d9a3335e389c2cead541e40df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 5 Sep 2025 16:58:57 +0200 Subject: [PATCH 3/6] Reword with focus on trade-offs --- src/doc/src/guide/build-performance.md | 44 +++++++++++++++----------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/src/doc/src/guide/build-performance.md b/src/doc/src/guide/build-performance.md index 808c05b8f4c..66fbb70e951 100644 --- a/src/doc/src/guide/build-performance.md +++ b/src/doc/src/guide/build-performance.md @@ -1,38 +1,44 @@ # 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: +Cargo uses configuration defaults that try to balance various aspects, including debuggability, runtime performance, build performance, binary size and others. Because of that, build performance is sometimes traded off for other benefits which may not be as important for your circumstances. This guide will step you through changes you can make to improve build performance. -- Modify compiler or Cargo flags -- Modify the source code of your crate(s) +Same as when optimizing runtime performance, be sure to measure these changes against the workflows you actually care about, as we provide general guidelines and your circumstances may be different. -This guide focuses on the first approach. +Example workflows to consider include: +- Compiler feedback as you develop (`cargo check` after making a code change) +- Test feedback as you develop (`cargo test` after making a code change) +- CI builds -Below, you can find several methods that can be used to optimize build performance. It is important to note 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. - -Note that some of these approaches currently require using the nightly toolchain. +Note that some approaches described below currently require using the nightly toolchain. ## Reduce amount of generated debug information -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. +Recommendation: Add to your `Cargo.toml` (for maintainers) or `$CARGO_HOME/.cargo/config.toml` (for contributors): -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: +debug = "line-tables-only" -```toml -[profile.dev] +[profile.dev.package."*"] debug = false -[profile.dev.package] -.debug = true +[profile.debugging] +inherits = "dev" +debug = true ``` +This will: +- Change the [`dev` profile](../reference/profiles.md#dev) (default for development commands) to: + - Limit [debug information](../reference/profiles.md#debug) for workspace members to what is needed for useful panic backtraces + - Avoid generating any debug information for dependencies +- Provide an opt-in for when debugging via [`--profile debugging`](../reference/profiles.md#custom-profiles) + +Trade-offs: +- ✅ Faster per-crate build times +- ✅ Faster link times +- ✅ Smaller disk usage of the `target` directory +- ❌ Requires a full rebuild to have a high-quality debugger experience + ## Use an alternative codegen backend > **This requires nightly/unstable features** From 97ec21d911e693c5a02e329e4458616265538be2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 5 Sep 2025 17:22:02 +0200 Subject: [PATCH 4/6] Add configuration changes section --- src/doc/src/guide/build-performance.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/doc/src/guide/build-performance.md b/src/doc/src/guide/build-performance.md index 66fbb70e951..9a79ed061b9 100644 --- a/src/doc/src/guide/build-performance.md +++ b/src/doc/src/guide/build-performance.md @@ -9,11 +9,11 @@ Example workflows to consider include: - Test feedback as you develop (`cargo test` after making a code change) - CI builds -Note that some approaches described below currently require using the nightly toolchain. +All approaches described below require you to modify [Cargo configuration](#where-to-apply-configuration-changes). Note that some of them currently require using the nightly toolchain. ## Reduce amount of generated debug information -Recommendation: Add to your `Cargo.toml` (for maintainers) or `$CARGO_HOME/.cargo/config.toml` (for contributors): +Recommendation: Add to your `Cargo.toml` or `.cargo/config.toml`: ```toml [profile.dev] @@ -60,3 +60,12 @@ 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). 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. + + +## Where to apply configuration changes + +You can apply the configuration changes described above in several places: + +- If you apply them to the `Cargo.toml` manifest, they will affect all developers who work on the given crate/project. +- If you apply them to the `/.cargo/config.toml` file, they will affect only you (unless this file is checked into version control). +- If you apply them to the `$CARGO_HOME/.cargo/config.toml` file, they will be applied globally to all Rust projects that you work on. From df7e02dbf0a3e55f8da0615aeb187d0fade6c68b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 6 Sep 2025 11:36:41 +0200 Subject: [PATCH 5/6] Split text into two sections --- src/doc/src/guide/build-performance.md | 69 ++++++++++++++------------ 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/src/doc/src/guide/build-performance.md b/src/doc/src/guide/build-performance.md index 9a79ed061b9..2a1b7247b2e 100644 --- a/src/doc/src/guide/build-performance.md +++ b/src/doc/src/guide/build-performance.md @@ -1,17 +1,23 @@ # Optimizing Build Performance -Cargo uses configuration defaults that try to balance various aspects, including debuggability, runtime performance, build performance, binary size and others. Because of that, build performance is sometimes traded off for other benefits which may not be as important for your circumstances. This guide will step you through changes you can make to improve build performance. +This guide will step you through Cargo configuration options and source code organization patterns that can help improve build performance, by prioritizing it over other aspects which may not be as important for your circumstances. -Same as when optimizing runtime performance, be sure to measure these changes against the workflows you actually care about, as we provide general guidelines and your circumstances may be different. +Same as when optimizing runtime performance, be sure to measure these changes against the workflows you actually care about, as we provide general guidelines and your circumstances may be different, it is possible that some of these approaches might actually make build performance worse for your use-case. Example workflows to consider include: - Compiler feedback as you develop (`cargo check` after making a code change) - Test feedback as you develop (`cargo test` after making a code change) - CI builds -All approaches described below require you to modify [Cargo configuration](#where-to-apply-configuration-changes). Note that some of them currently require using the nightly toolchain. +## Cargo and Compiler Configuration -## Reduce amount of generated debug information +> Note that some approaches described in this section currently require using the nightly toolchain. + +Cargo uses configuration defaults that try to balance several aspects, including debuggability, runtime performance, build performance, binary size and others. This section describes several approaches for changing these defaults that should be designed to maximize build performance. + +You can set the described options either in the [`Cargo.toml` manifest](../reference/profiles.md), which will make them available for all developers who work on the given crate/project, or in the [`config.toml` configuration file](../reference/config.md), where you can apply them only for you or even globally for all your local projects. + +### Reduce amount of generated debug information Recommendation: Add to your `Cargo.toml` or `.cargo/config.toml`: @@ -29,43 +35,42 @@ debug = true This will: - Change the [`dev` profile](../reference/profiles.md#dev) (default for development commands) to: - - Limit [debug information](../reference/profiles.md#debug) for workspace members to what is needed for useful panic backtraces - - Avoid generating any debug information for dependencies + - Limit [debug information](../reference/profiles.md#debug) for workspace members to what is needed for useful panic backtraces + - Avoid generating any debug information for dependencies - Provide an opt-in for when debugging via [`--profile debugging`](../reference/profiles.md#custom-profiles) Trade-offs: -- ✅ Faster per-crate build times +- ✅ Faster build times - ✅ Faster link times -- ✅ Smaller disk usage of the `target` directory +- ✅ Smaller disk usage of the `target` directory - ❌ Requires a full rebuild to have a high-quality debugger experience -## Use an alternative codegen backend +### 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). +Recommendation: -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. +- Install the Cranelift codegen backend rustup component + ```console + $ rustup component add rustc-codegen-cranelift-preview --toolchain nightly + ``` +- Add to your `Cargo.toml` or `.cargo/config.toml`: + ```toml + [profile.dev] + codegen-backend = "cranelift" + ``` +- Run Cargo with `-Z codegen-backend` or enable the [`codegen-backend`](../reference/unstable.md#codegen-backend) feature in `.cargo/config.toml`. + - This is required because this is currently an unstable feature. +This will change the [`dev` profile](../reference/profiles.md#dev) to use the [Cranelift codegen backend](https://github.com/rust-lang/rustc_codegen_cranelift) for generating machine code, instead of the default LLVM backend. The Cranelift backend should generate code faster than LLVM, which should result in improved build performance. -## Where to apply configuration changes - -You can apply the configuration changes described above in several places: - -- If you apply them to the `Cargo.toml` manifest, they will affect all developers who work on the given crate/project. -- If you apply them to the `/.cargo/config.toml` file, they will affect only you (unless this file is checked into version control). -- If you apply them to the `$CARGO_HOME/.cargo/config.toml` file, they will be applied globally to all Rust projects that you work on. +Trade-offs: +- ✅ Faster build times +- ❌ Worse runtime performance of the generated code +- ❌ Requires using nightly Rust and an unstable feature +- ❌ Only available for [certain targets](https://github.com/rust-lang/rustc_codegen_cranelift?tab=readme-ov-file#platform-support) +- ❌ Might not support all Rust features (e.g. unwinding) + +## Source code organization +TODO From 5c1631ce6254214246769d2c445ee250f9029a94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 10 Sep 2025 16:52:51 +0200 Subject: [PATCH 6/6] Reword intro, remove nightly/unstable feature sub-headings, clarify Cranelift backend trade-offs, remove TODO --- src/doc/src/guide/build-performance.md | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/doc/src/guide/build-performance.md b/src/doc/src/guide/build-performance.md index 2a1b7247b2e..a9e46f673fb 100644 --- a/src/doc/src/guide/build-performance.md +++ b/src/doc/src/guide/build-performance.md @@ -1,6 +1,6 @@ # Optimizing Build Performance -This guide will step you through Cargo configuration options and source code organization patterns that can help improve build performance, by prioritizing it over other aspects which may not be as important for your circumstances. +Cargo configuration options and source code organization patterns can help improve build performance, by prioritizing it over other aspects which may not be as important for your circumstances. Same as when optimizing runtime performance, be sure to measure these changes against the workflows you actually care about, as we provide general guidelines and your circumstances may be different, it is possible that some of these approaches might actually make build performance worse for your use-case. @@ -11,8 +11,6 @@ Example workflows to consider include: ## Cargo and Compiler Configuration -> Note that some approaches described in this section currently require using the nightly toolchain. - Cargo uses configuration defaults that try to balance several aspects, including debuggability, runtime performance, build performance, binary size and others. This section describes several approaches for changing these defaults that should be designed to maximize build performance. You can set the described options either in the [`Cargo.toml` manifest](../reference/profiles.md), which will make them available for all developers who work on the given crate/project, or in the [`config.toml` configuration file](../reference/config.md), where you can apply them only for you or even globally for all your local projects. @@ -47,8 +45,6 @@ Trade-offs: ### Use an alternative codegen backend -> **This requires nightly/unstable features** - Recommendation: - Install the Cranelift codegen backend rustup component @@ -66,11 +62,9 @@ Recommendation: This will change the [`dev` profile](../reference/profiles.md#dev) to use the [Cranelift codegen backend](https://github.com/rust-lang/rustc_codegen_cranelift) for generating machine code, instead of the default LLVM backend. The Cranelift backend should generate code faster than LLVM, which should result in improved build performance. Trade-offs: -- ✅ Faster build times +- ✅ Faster code generation (`cargo build`) +- ❌ **Requires using nightly Rust and an unstable Cargo feature** - ❌ Worse runtime performance of the generated code -- ❌ Requires using nightly Rust and an unstable feature + - Speeds up build part of `cargo test`, but might increase its test execution part - ❌ Only available for [certain targets](https://github.com/rust-lang/rustc_codegen_cranelift?tab=readme-ov-file#platform-support) - ❌ Might not support all Rust features (e.g. unwinding) - -## Source code organization -TODO