Benchmarking with BenchmarkTools shows that your explicit loop is actually faster:
julia> function f1(x, y, n, m)
for j=1:n
for i=1:m
y[i] = x[i,j]
end
end
end
f1 (generic function with 1 method)
julia> function f2(x, y, n)
for j=1:n
y .= x[:,j]
end
end
f2 (generic function with 1 method)
julia> using BenchmarkTools
julia> @benchmark f1($x, $y, $n, $m)
BenchmarkTools.Trial:
memory estimate: 0 bytes
allocs estimate: 0
--------------
minimum time: 20.441 ms (0.00% GC)
median time: 20.733 ms (0.00% GC)
mean time: 20.810 ms (0.00% GC)
maximum time: 22.094 ms (0.00% GC)
--------------
samples: 241
evals/sample: 1
julia> @benchmark f2($x, $y, $n)
BenchmarkTools.Trial:
memory estimate: 191.26 MiB
allocs estimate: 19489
--------------
minimum time: 42.840 ms (7.15% GC)
median time: 43.673 ms (8.05% GC)
mean time: 43.704 ms (7.84% GC)
maximum time: 47.225 ms (6.91% GC)
--------------
samples: 115
evals/sample: 1
That’s because x[:, j]
makes a copy of that slice of the array. You can make a view instead, which doesn’t copy the data:
julia> function f3(x, y, n)
for j=1:n
y .= @view(x[:, j])
end
end
f3 (generic function with 1 method)
julia> @benchmark f3($x, $y, $n)
BenchmarkTools.Trial:
memory estimate: 0 bytes
allocs estimate: 0
--------------
minimum time: 13.306 ms (0.00% GC)
median time: 13.952 ms (0.00% GC)
mean time: 14.013 ms (0.00% GC)
maximum time: 15.861 ms (0.00% GC)
--------------
samples: 357
evals/sample: 1
That’s even better than your explicit loop, but you can make your loop just as fast by turning off bounds checks (of course, this is only OK if you actually check the sizes of your arrays to ensure you won’t access out of bounds):
julia> function f4(x, y, n, m)
for j=1:n
for i=1:m
@inbounds y[i] = x[i,j]
end
end
end
f4 (generic function with 1 method)
julia> @benchmark f4($x, $y, $n, $m)
BenchmarkTools.Trial:
memory estimate: 0 bytes
allocs estimate: 0
--------------
minimum time: 13.205 ms (0.00% GC)
median time: 13.421 ms (0.00% GC)
mean time: 13.448 ms (0.00% GC)
maximum time: 14.155 ms (0.00% GC)
--------------
samples: 372
evals/sample: 1