减速0.5和0.6?

时间:2017-03-16 06:35:21

标签: performance iteration julia

我正在将我的代码从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中发生了什么?

1 个答案:

答案 0 :(得分:10)

您在全局范围内使用非常量全局变量和时序代码。使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。避免全局变量是第一部分。