我正在将我的代码从 Julia 0.4 更新到 0.5,我遇到了一些速度下降的问题。我遇到的一个简单例子是
x = rand(1:100, (50, 7, 3))
function f(a::Int, e::Int, r::Int)
x[a-16+1, e-10+1, r]
end
y = sum(f(a, e, r) for a in 16:65, e in 10:16, r in 1:3) # in 0.5 and 0.6
y = sum([f(a, e, r) for a in 16:65, e in 10:16, r in 1:3]) # in 0.4
在 0.4 中,最后一行(使用列表理解)需要 0.0004 秒,而在 0.5 和 0.6 中,它需要大约 0.1376 秒。 0.5 和 0.6 版发生了什么?
最佳答案
您在全局范围内使用非常量全局变量和计时代码。使 x
常量(或将其作为函数参数传递)并将 sum
计算放在函数中:
const x = rand(1:100, (50, 7, 3))
function f(a::Int, e::Int, r::Int)
x[a-16+1, e-10+1, r]
end
g() = sum(f(a, e, r) for a in 16:65, e in 10:16, r in 1:3) # in 0.5 and 0.6
h() = sum([f(a, e, r) for a in 16:65, e in 10:16, r in 1:3]) # in 0.4
当我运行您的原始代码时,我看到的时间与您报告的时间几乎完全相同。使用我编写的代码:
0.6.0-pre.alpha.117:
julia> g(); @time g() # Call g() before timing it to compile it
0.000020 seconds (9 allocations: 416 bytes)
53033
julia> h(); @time h()
0.000026 seconds (6 allocations: 8.547 KiB)
53033
0.4.7:
julia> h(); @time h()
0.000020 seconds (6 allocations: 8.453 KB)
50658
现在速度如此之快,您无法再仅通过一次运行就对其进行精确的基准测试。
是的,在您原来的情况下,0.5 和 0.6 确实变慢了。这是因为它现在为理解/生成器构造一个特殊的函数对象并对其进行编译。因此,当您在顶层运行这些语句时,您每次都在支付(和衡量)编译成本。当你把它放在一个函数中时,Julia 能够编译一次,然后每次后续调用都非常快。我强烈建议阅读所有 performance tips如果您对优化性能感兴趣。避免全局变量是第一部分。
关于performance - 0.5和0.6减速?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42826871/