Strange performance difference between const and var

I’ve noticed some unexpected differences in performance when I change variables from var to const. My assumption would have been that when a value is const, it allows the compiler to make assumptions about the value that allow it to make more optimisations. Put another way, changing a field from var to const (provided it still compiles) shouldn’t result in a reduction of performance. After all, as long as the code in question isn’t actually mutating the variable, you should be able to compile to the exact same machine code.
Now, consider the following example.

var a : f32 = 0;
var b : f32 = 1;
_ = &b;
const t1 = std.time.nanoTimestamp();
for(0..1000000000) |_|
{
    a = b;
}
const t2 = std.time.nanoTimestamp();
std.debug.print("A billion loads took {d}s\n", .{@as(f64, @floatFromInt(t2-t1)) / 1000000000.0,});

The output of this on my machine is A billion loads took 0.68401276s. If you run the same code with b changed to a const, the output is A billion loads took 5.575363483s, meaning it takes roughly 8x longer.
Is this expected behaviour, and if so, why?

I assume you are running benchmark in Debug mode because in release mode this for loop would be optimized away.

So running benchmark in Debug mode on master compiler version with x86_64 backend on my machine actually tells opposite story. Const is slightly faster.

P.S. here is result for -O ReleaseFast which are obviously the same

That’s right. I was originally actually doing something with the data, but when I saw the performance difference, I distilled it down to this example, which is obviously not going to appear anywhere in real life.
I was using 0.15.1, so that would explain the difference. I guess I should’ve considered that it was one of the earliest releases using the self-hosted backend as default. Thanks!

I tried it on 0.15.1 and manged to reproduce your findings. Its also x8 longer

This is likely due to the new x86_64 backend outputting worse machine code than LLVM in debug mode.

Probably worth to run it in Godbolt and opening an issue given the stark difference.

2 Likes

0.15.1 and master both use x86_64 backend so bug is already fixed

2 Likes