I did some test myself as below, it turns out the loop version of my code is close to 15 times faster.
Why? What made Julia so fast when going through a loop?
My code:
A = rand(1:100, 10^5,1);
@time Ind1 = A .> 35;
function f(x)
Ind = fill(NaN, 10^5,1);
for i in 1:10^5
Ind[i] = x[i]>35;
end
return Ind;
end
@time Ind2 = f(A);
The results:
0.205660 seconds (1.00 M allocations: 50.089 MiB, 2.73% gc time, 99.87% compilation time)
0.015716 seconds (78.34 k allocations: 5.216 MiB, 96.73% compilation time)
While the advice about global variables is generally true and very useful, I think in this case it doesn’t make much difference since both are ultimately dealing with the global variable A anyway. The loop version actually turns out to be slower as I posted above, but that’s mostly due to the bounds checking in the loop. This version is much faster:
julia> function f(x)
Ind = Vector{Bool}(undef, 10^5);
for i in 1:10^5
@inbounds Ind[i] = x[i]>35;
end
return Ind;
end
julia> @time Ind2 = f(A); # compilation run
0.081470 seconds (46.49 k allocations: 3.090 MiB, 99.79% compilation time)
julia> @time Ind2 = f(A);
0.000136 seconds (2 allocations: 97.766 KiB)
I was just thinking that my computer must be much slower (and it likely is), because in your original code (measuring the compilation times), where you get 0.2 and 0.01 seconds, my system needed 2 and 0.06 seconds respectively.
Mine is a measly AMD A10 2.4 GHz/4 GB RAM machine running Linux.
Yeah, I just ran some (with a setup to avoid any caching shenanigans from reusing the same vector A). Getting rid of the global (and using a let-local vector) helps a lot as expected, and the @inbounds version and the broadcast .> version are pretty close: