The difference you are seeing seems to be spurious, it’s just one-time compilation/startup costs. If I use @btime from BenchmarkTools.jl instead of @time, it reports exactly the same time (389µs) in both cases. (The @btime macro performs the measurement several times and reports the smallest, and it is generally far more reliable than @time for drawing conclusions about performance.)
I guess @btime has to do some magic stuff that doesn’t allow you to see the problem. But when I found the problem it was because a program that usually ran in one second was taking several minutes.
By multiplying the number of iterations of the loop by 100 and removing the @time the first program takes about a 10s while the second is instantaneous.
So the problem remains and is very similar to the performance problem of global variables
Replacing the let block with a function is sufficient to completely eliminate the problem for me. That seems like it would also solve the issue in your actual program, since it’s easy to turn a bare let block into a function.
Probably you should report an issue about that. Clearly something strange is happening there. The same happens with begin...end blocks:
start julia and:
julia> @time begin
f() = nothing
let
s = 0
for n in 1:100000
s += n^10
end
s
end
end
0.142710 seconds (500.56 k allocations: 9.295 MiB, 4.71% gc time, 5.31% compilation time)
-5724124746025484656
julia> @time begin
f() = nothing
let
s = 0
for n in 1:100000
s += n^10
end
s
end
end
0.146696 seconds (498.21 k allocations: 9.129 MiB)
-5724124746025484656
restart julia and:
julia> @time begin
let
s = 0
for n in 1:100000
s += n^10
end
s
end
end
0.000568 seconds
-5724124746025484656