Skip to content

refactor: replace format! with concat! for string literals #134212

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

Closed
wants to merge 1 commit into from
Closed

refactor: replace format! with concat! for string literals #134212

wants to merge 1 commit into from

Conversation

Integral-Tech
Copy link
Contributor

@Integral-Tech Integral-Tech commented Dec 12, 2024

Although format! macro is very powerful, it introduces overhead of memory allocation on the heap compared to &str. Therefore, when format! macro is unnecessary, concat! is a better choice in terms of performance.

@rustbot
Copy link
Collaborator

rustbot commented Dec 12, 2024

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @SparrowLii (or someone else) some time within the next two weeks.

Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (S-waiting-on-review and S-waiting-on-author) stays updated, invoking these commands when appropriate:

  • @rustbot author: the review is finished, PR author should check the comments and take action accordingly
  • @rustbot review: the author is ready for a review, this PR will be queued again in the reviewer's queue

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. labels Dec 12, 2024
@rustbot
Copy link
Collaborator

rustbot commented Dec 12, 2024

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

Some changes occurred in src/tools/rustfmt

cc @rust-lang/rustfmt

The Miri subtree was changed

cc @rust-lang/miri

Copy link
Member

@jieyouxu jieyouxu left a comment

Choose a reason for hiding this comment

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

I don't find this change to be more readable, and I don't think there will be any observable change in performance to justify the change on perf grounds as a tradeoff.

@Integral-Tech
Copy link
Contributor Author

Integral-Tech commented Dec 12, 2024

I don't find this change to be more readable, and I don't think there will be any observable change in performance to justify the change on perf grounds as a tradeoff.

format! constructs String during runtime, while concat! constructs &str during compilation. Therefore, concat! is more efficient than format!.

@bjorn3
Copy link
Member

bjorn3 commented Dec 12, 2024

The perf difference rounds to zero when the code in question already takes up almost no time. Outside of the couple of cases I indicated where this change is not valid, basically all places you made the change are either tests or in code that only runs when you request a help message. The performance of tests doesn't matter and nobody is going to notice a help message taking like 10μs longer to render due to an extra allocation.

@rust-log-analyzer
Copy link
Collaborator

The job x86_64-gnu-llvm-18 failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)
#16 exporting to docker image format
#16 sending tarball 26.6s done
#16 DONE 32.5s
##[endgroup]
Setting extra environment values for docker:  --env ENABLE_GCC_CODEGEN=1 --env GCC_EXEC_PREFIX=/usr/lib/gcc/
[CI_JOB_NAME=x86_64-gnu-llvm-18]
debug: `DISABLE_CI_RUSTC_IF_INCOMPATIBLE` configured.
---
sccache: Starting the server...
##[group]Configure the build
configure: processing command line
configure: 
configure: build.configure-args := ['--build=x86_64-unknown-linux-gnu', '--llvm-root=/usr/lib/llvm-18', '--enable-llvm-link-shared', '--set', 'rust.randomize-layout=true', '--set', 'rust.thin-lto-import-instr-limit=10', '--enable-verbose-configure', '--enable-sccache', '--disable-manage-submodules', '--enable-locked-deps', '--enable-cargo-native-static', '--set', 'rust.codegen-units-std=1', '--set', 'dist.compression-profile=balanced', '--dist-compression-formats=xz', '--set', 'rust.lld=false', '--disable-dist-src', '--release-channel=nightly', '--enable-debug-assertions', '--enable-overflow-checks', '--enable-llvm-assertions', '--set', 'rust.verify-llvm-ir', '--set', 'rust.codegen-backends=llvm,cranelift,gcc', '--set', 'llvm.static-libstdcpp', '--enable-new-symbol-mangling']
configure: target.x86_64-unknown-linux-gnu.llvm-config := /usr/lib/llvm-18/bin/llvm-config
configure: llvm.link-shared     := True
configure: rust.randomize-layout := True
configure: rust.thin-lto-import-instr-limit := 10
---
[BUILD] sysroot None
error[E0061]: this function takes 1 argument but 2 arguments were supplied
##[error]   --> /checkout/compiler/rustc_codegen_cranelift/scripts/rustdoc-clif.rs:23:19
    |
23  |         args.push(OsString::from(concat!("-Zcodegen-backend="), env!("BUILTIN_BACKEND")))
    |                   ^^^^^^^^^^^^^^                                ----------------------- unexpected argument #2 of type `&'static str`
note: associated function defined here
   --> /checkout/library/core/src/convert/mod.rs:585:8
    |
585 |     fn from(value: T) -> Self;
585 |     fn from(value: T) -> Self;
    |        ^^^^
help: remove the extra argument
    |
23  -         args.push(OsString::from(concat!("-Zcodegen-backend="), env!("BUILTIN_BACKEND")))
23  +         args.push(OsString::from(concat!("-Zcodegen-backend=")))

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0061`.
For more information about this error, try `rustc --explain E0061`.
env -u TOOLCHAIN_NAME BUILTIN_BACKEND="cranelift" CARGO="/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" RUSTC="/checkout/obj/build/bootstrap/debug/rustc" RUSTDOC="/checkout/obj/build/bootstrap/debug/rustdoc" "/checkout/obj/build/bootstrap/debug/rustc" "/checkout/compiler/rustc_codegen_cranelift/scripts/rustdoc-clif.rs" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-tools/cg_clif/dist/rustdoc-clif" "-Cstrip=debuginfo" exited with status ExitStatus(unix_wait_status(256))
Command has failed. Rerun with -v to see more details.
  local time: Thu Dec 12 14:16:34 UTC 2024
  network time: Thu, 12 Dec 2024 14:16:34 GMT
##[error]Process completed with exit code 1.
Post job cleanup.

@Integral-Tech
Copy link
Contributor Author

The perf difference rounds to zero when the code in question already takes up almost no time. Outside of the couple of cases I indicated where this change is not valid, basically all places you made the change are either tests or in code that only runs when you request a help message. The performance of tests doesn't matter and nobody is going to notice a help message taking like 10μs longer to render due to an extra allocation.

What about this change?

diff --git a/src/tools/clippy/lintcheck/src/main.rs b/src/tools/clippy/lintcheck/src/main.rs
index 8c62dd3ed38..bf3f8ca9802 100644
--- a/src/tools/clippy/lintcheck/src/main.rs
+++ b/src/tools/clippy/lintcheck/src/main.rs
@@ -88,15 +88,13 @@ fn run_clippy_lints(
             );
         }
 
-        let cargo_home = env!("CARGO_HOME");
-
         // `src/lib.rs` -> `target/lintcheck/sources/crate-1.2.3/src/lib.rs`
         let remap_relative = format!("={}", self.path.display());
         // Fallback for other sources, `~/.cargo/...` -> `$CARGO_HOME/...`
-        let remap_cargo_home = format!("{cargo_home}=$CARGO_HOME");
+        let remap_cargo_home = concat!(env!("CARGO_HOME"), "=$CARGO_HOME");
         // `~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crate-2.3.4/src/lib.rs`
         //     -> `crate-2.3.4/src/lib.rs`
-        let remap_crates_io = format!("{cargo_home}/registry/src/index.crates.io-6f17d22bba15001f/=");
+        let remap_crates_io = concat!(env!("CARGO_HOME"), "/registry/src/index.crates.io-6f17d22bba15001f/=");
 
         let mut clippy_args = vec![
             "--remap-path-prefix",

@bjorn3
Copy link
Member

bjorn3 commented Dec 12, 2024

Lintcheck is a tool that is only used during development of Clippy: https://github.com/rust-lang/rust-clippy/blob/master/lintcheck/README.md

@oli-obk
Copy link
Contributor

oli-obk commented Dec 12, 2024

I think this is a case of premature optimization. While you are correct about the unnecessary allocations, all the use cases are not going to benefit us (too small, mostly in error, code)

Thus I'm closing this PR. Please don't hesitate to look for more avenues for optimizations. If you want to get opinions on ideas before doing work, feel free to start a thread on Zulip in the t-compiler stream

@oli-obk oli-obk closed this Dec 12, 2024
@Integral-Tech Integral-Tech deleted the format-concat branch December 12, 2024 14:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants