ITADN

Question: How to correctly handle the return value?

#886OpenStovent 创建于 2025-09-28
S
Stoventcommented
Hi, I got a question that I could not find the answer from the book or the documentation: How do you properly make sure the return value of the benchmarked function is never optimized away? I see two ways of doing it: the getting started example implicitly returns the value of the fibonacci function from the closure, which I guess is intentional to make sure the computation is not optimized away (not dead code). The other way is to send it to black_box (as stated in the [std doc](https://doc.rust-lang.org/std/hint/fn.black_box.html#when-is-this-useful)), and thus we force the compiler to not remove the return value. However I noticed a third way which is to both send the return value to black_back AND to implicitly return it. I tested the three on one of my functions (stripped for clarity): ```rs c.bench_function("size_effective_address_immediate implicit return", |b| b.iter(|| { size_effective_address_immediate(black_box(andi), &mut memory_iter) })); c.bench_function("size_effective_address_immediate black_box", |b| b.iter(|| { black_box(size_effective_address_immediate(black_box(andi), &mut memory_iter)); })); c.bench_function("size_effective_address_immediate black_box implicit return", |b| b.iter(|| { black_box(size_effective_address_immediate(black_box(andi), &mut memory_iter)) // no ; at the end })); ``` And the benchmark results are not the same based on how the return value is treated. It seems returning the value takes more time and thus is better for an accurate result? ``` size_effective_address_immediate implicit return time: [10.961 ns 11.000 ns 11.046 ns] change: [−1.2148% −0.3369% +0.5794%] (p = 0.47 > 0.05) No change in performance detected. size_effective_address_immediate black_box time: [8.2919 ns 8.3235 ns 8.3626 ns] change: [−0.7658% +0.2887% +1.4662%] (p = 0.62 > 0.05) No change in performance detected. size_effective_address_immediate black_box implicit return time: [10.975 ns 11.017 ns 11.059 ns] change: [−0.7647% +0.2208% +1.2257%] (p = 0.67 > 0.05) No change in performance detected. ``` So what is the best way to handle the return value? Thank you for the help! <details> <summary>Below is the full code of each of the three examples for reference</summary> ```rs { let andi = 0x02B9; // Long, absolute long EA. let mut code_andi = [andi, 0x0000, 0x0000, 0x0000, 0x0000]; c.bench_function("size_effective_address_immediate implicit return", |b| b.iter(|| { let mut memory_iter = code_andi.iter_u16(2); size_effective_address_immediate(black_box(andi), &mut memory_iter) })); } { let andi = 0x02B9; // Long, absolute long EA. let mut code_andi = [andi, 0x0000, 0x0000, 0x0000, 0x0000]; c.bench_function("size_effective_address_immediate black_box", |b| b.iter(|| { let mut memory_iter = code_andi.iter_u16(2); black_box(size_effective_address_immediate(black_box(andi), &mut memory_iter)); })); } { let andi = 0x02B9; // Long, absolute long EA. let mut code_andi = [andi, 0x0000, 0x0000, 0x0000, 0x0000]; c.bench_function("size_effective_address_immediate black_box implicit return", |b| b.iter(|| { let mut memory_iter = code_andi.iter_u16(2); black_box(size_effective_address_immediate(black_box(andi), &mut memory_iter)) })); } ``` </details>
0 条评论