gpt4 book ai didi

performance - Julia:函数类型和性能

转载 作者:行者123 更新时间:2023-12-03 16:00:05 24 4
gpt4 key购买 nike

在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
不幸的是,“显而易见的”通用版本具有糟糕的wrt性能:
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

最佳答案

原因是每次调用x -> sqrt(x)compute_sum2被定义为一个新的匿名函数,因此每次调用它都会导致新的编译。
如果您甚至在例如之前定义它像这样:

julia> f = x -> sqrt(x)
那么你有:
julia> @time compute_sum2(xs, f) # here you pay compilation cost
0.010053 seconds (19.46 k allocations: 1.064 MiB)
665.2469135020949

julia> @time compute_sum2(xs, f) # here you have already compiled everything
0.000003 seconds (1 allocation: 16 bytes)
665.2469135020949
请注意,自然的方法是使用以下名称定义函数:
julia> g(x) = sqrt(x)
g (generic function with 1 method)

julia> @time compute_sum2(xs, g)
0.000002 seconds
665.2469135020949
您可以看到 x -> sqrt(x)每次编写时都会遇到一个新的匿名函数,例如:
julia> typeof(x -> sqrt(x))
var"#3#4"

julia> typeof(x -> sqrt(x))
var"#5#6"

julia> typeof(x -> sqrt(x))
var"#7#8"
请注意,如果在函数主体中定义匿名函数,则情况会有所不同:
julia> h() = typeof(x -> sqrt(x))
h (generic function with 2 methods)

julia> h()
var"#11#12"

julia> h()
var"#11#12"

julia> h()
var"#11#12"
您会看到这次每次匿名功能都是相同的。

关于performance - Julia:函数类型和性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64101026/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com