This is too simplistic example to give any meaningful answer. What’s Type
? What’s value
? If it’s i32
and 42
than they both compile to the exact same thing. But if Type
is Drop
than the second will call the destructor on each iteration. (I’ve also written previously about similar example with BorrowedBuf
^1^).
Rust Programming
Side note, don't fall into the trap of premature optimization. You'll more than likely end up shooting yourself in the foot for something that usually doesn't matter in most cases.
Functionally equivalent, the compiler will optimize lots for you. As the programmer, your focus should be on whether that variable is relevant to the loop's scope exclusively or not (i.e. if you need to access the variable after the loop has modified it). If not, keep it in the loop so that its easier to read your code.
I would say that they are equivalent. If I'm not mistaken, let
statements only reserves space on the stack, and this only increments the stack register.
And on the latter snippet, the compiler would certainly not bother to modify the stack pointer as the type doesn't change.
according to godbolt: https://rust.godbolt.org/z/hP5Y3qMPW
use rand::random;
pub fn main1() {
let mut var : u128;
loop {
var = random();
}
}
pub fn main2() {
loop {
let var : u128 = random();
}
}
compiles to:
example::main1::h45edf333d7832d08:
.Lfunc_begin8:
sub rsp, 24
.LBB8_1:
.Ltmp80:
mov rax, qword ptr [rip + rand::random::he3c23ceb967a3e28@GOTPCREL]
call rax
mov qword ptr [rsp + 8], rdx
mov qword ptr [rsp], rax
jmp .LBB8_1
.Ltmp81:
.Lfunc_end8:
example::main2::h1a899b25b96d66db:
.Lfunc_begin9:
sub rsp, 24
.LBB9_1:
.Ltmp82:
mov rax, qword ptr [rip + rand::random::he3c23ceb967a3e28@GOTPCREL]
call rax
mov qword ptr [rsp + 8], rdx
mov qword ptr [rsp], rax
jmp .LBB9_1
.Ltmp83:
.Lfunc_end9:
jmp .LBB9_1
So yeah, exactly the same thing.
Fascinating! Thank you for sharing this.
let
statements only reserves space on the stack
It is not guaranteed to do that. It could also use a register or be optimized out completly (like in the example you posted in the other comment).
The stack pointer is also not changed for each local variable, but instead for each function call, so it wouldn't make a difference anyway.
Ok! Thanks for the clarification !
Without context, there's no reason to compare the performance of these. The compiler is complex enough that what you do in the loop and after the loop matters with regards to optimizations.
Do you have more context? What's actually happening in the code?