As a followup from this:
Matt has shown that enumerate(eachindex(a))
is quite fast:
julia> function f!(A)
for (count, idx) in enumerate(eachindex(A))
A[idx] = count*2
end
end
julia> function g!(A)
i = 0
for idx in eachindex(A)
i += 1
A[idx] = i*2
end
end
julia> a = rand(1:10,10^5);
julia> @btime f!($a)
31.433 μs (0 allocations: 0 bytes)
julia> @btime g!($a)
75.225 μs (0 allocations: 0 bytes)
But all the difference disappears by using @inbounds
, which has quite an important performance effect for both functions:
julia> function f2!(A)
for (count, idx) in enumerate(eachindex(A))
@inbounds A[idx] = count*2
end
end
f2! (generic function with 1 method)
julia> @btime f2!($a)
18.272 μs (0 allocations: 0 bytes)
julia> function g2!(A)
i = 0
for idx in eachindex(A)
i += 1
@inbounds A[idx] = i*2
end
end
g2! (generic function with 1 method)
julia> @btime g2!($a)
18.063 μs (0 allocations: 0 bytes)
This would be one case where disabling bounds checking seems perfectly safe. (The llvm codes do not appear identical, though).
In this case the inbounds
could be deduced by the compiler in both cases. Shouldn’t it?