1

My (limited) understanding is that format!("{}", v) and format!("{}", &v) are essentially identical, and should generate identical assembly code and identical performance results. This is based on reading Does println! borrow or own the variable?). Yet, when comparing these two functions, the assembly is somewhat different. Is this expected, or is this a missing Rust compiler optimization? Or is there some edge case in which it is important to generate different code?

pub fn bar(j: i32) -> String {
    format!("bar {}", j)
}

// vs

pub fn foo(i: i32) -> String {
    format!("foo {}", &i)
}

Benchmarks

Running benchmarks produces ~6% difference in performance:

Performance comparison graph

See also

3
  • I think it's because <&i32 as core::fmt::Display>::fmt doesn't get inlined. If it did, then I would expect the assembly to be identical. You can see this function gets emitted in the &i case, and then -- obviously -- foo has to actually give it the address of the i32 instead of the i32 itself. Commented May 30, 2023 at 3:40
  • @cdhowie is this declared somewhere in github.com/rust-lang/rust/blob/master/library/core/src/fmt/… ? Also, do you think this is a bug of a missing #[inline] ? Commented May 30, 2023 at 3:48
  • Not only; the formatting machinery is hard for LLVM to optimize as it's using dynamic dispatch. Commented May 30, 2023 at 6:03

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.