在Julia中,是否有一种方式可以将以下模式进行通用化?
function compute_sum(xs::Vector{Float64})
res = 0
for i in 1:length(xs)
res += sqrt(xs[i])
end
res
end
这会计算每个向量元素的平方根,然后将所有结果相加。与使用数组推导或 map
的“朴素”版本相比,它要快得多,也不需要额外分配内存:
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
很不幸,“显而易见”的通用版本在性能方面很糟糕:
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
fn
类型不明确,从而导致类型不稳定,但实际上是编译时间的问题。 - cno