For-loop in function is faster than global scope?

Why are loops faster in functions?
This:

a = [1:10_000_000;]
b = zeros(Int64, length(a))

function double!(x, y)
    L = length(x)
    for i in 1:L
        @inbounds y[i] = 2x[i]
    end
    nothing
end

@time double!(a, b)

is much faster than this:

@time begin    
    L = length(a)
    for i in 1:L
        @inbounds b[i] = 2a[i]
    end
end

https://docs.julialang.org/en/v1/manual/performance-tips/#Avoid-global-variables

5 Likes

Also, welcome to our community! :confetti_ball:

Complementing, the section about function barriers is also a little relevant. Basically, when the function is called passing a and b it is compiled optimized for two arguments of type Vector{Int64}, while when you do the loop accessing global variables (the only way to do so without a function or let body) the code cannot be optimized to assume a or b are of type Vector{Int64} because, as they are globals they can have their type changed by other parts of the code that the compiler is not looking at the moment.

4 Likes

Thanks to everyone