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

Yuri Astrakhan
  • 8,808
  • 6
  • 63
  • 97
  • 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. – cdhowie May 30 '23 at 03:40
  • @cdhowie is this declared somewhere in https://github.com/rust-lang/rust/blob/master/library/core/src/fmt/num.rs ? Also, do you think this is a bug of a missing `#[inline]` ? – Yuri Astrakhan May 30 '23 at 03:48
  • Not only; the formatting machinery is hard for LLVM to optimize as it's using dynamic dispatch. – Chayim Friedman May 30 '23 at 06:03

0 Answers0