Is there a way in Julia to generalise a pattern like the following?
function compute_sum(xs::Vector{Float64})
res = 0
for i in 1:length(xs)
res += sqrt(xs[i])
end
res
end
This computes the square-root of each vector element and then sums everything. It is much faster than the "naive" versions with array comprehension or map, and also doesn't allocate additional memory:
xs = rand(1000)
julia> @time compute_sum(xs)
0.000004 seconds
676.8372556762225
julia> @time sum([sqrt(x) for x in xs])
0.000013 seconds (3 allocations: 7.969 KiB)
676.837255676223
julia> @time sum(map(sqrt, xs))
0.000013 seconds (3 allocations: 7.969 KiB)
676.837255676223
Unfortunately the "obvious" generic version is terrible wrt performance:
function compute_sum2(xs::Vector{Float64}, fn::Function)
res = 0
for i in 1:length(xs)
res += fn(xs[i])
end
res
end
julia> @time compute_sum2(xs, x -> sqrt(x))
0.013537 seconds (19.34 k allocations: 1.011 MiB)
676.8372556762225