使用Julia的内置函数时性能下降

时间:2016-01-28 16:00:59

标签: performance julia

我参与的一个研究小组最近决定尝试从我们之前的编码语言迁移到Julia,因为除其他外,它声称的高速性能与其他用户友好的语言相比。但是,在我们最初的代码片段翻译中,我的一位合作伙伴注意到,与使用简单的循环技术相比,使用Julia的内置函数(特别是相当简单的函数,如'find')会导致速度下降十倍。还有其他人遇到过这种情况,还是有其他可能的原因我们应该研究一下?

1 个答案:

答案 0 :(得分:6)

请原谅对答案的评论,因为我没有代表做适当的评论......

我对朱莉娅的理解是,如果你正在钓鱼以获得最佳性能,通常会更好地编写循环。这已经有一段时间了;例如,见大华林的post about devectorizing expressions。 (编辑>但未来可能会发生变化;请参阅Colin T. Bowers关于多线程here的讨论以及下面的评论。)

请记住,判断表现可能会非常棘手。实际上,我在自己的代码中经常使用find因为我可以简洁地要求#<稀疏"中的非零值的Int索引。 Vector不是很长。与等效循环相比,find相对灵活,快速且清晰。例如:

# problem dimensions
p = 10000
k = 10

# a "sparse" vector with k random nonzeroes
b = zeros(p)
b[1:k] = randn(k)
shuffle!(b)

# use `find` to get the indices
@time bidx = find( x -> x .!= 0.0, b)

# is `find` faster than looping?
function find_nonzeroes(b, k)
    bnz = zeros(Int,k);
    j = 0
    @inbounds for i = 1:length(b)
        if b[i] .!= 0.0
            j += 1
            bnz[j] = i
        end
        j >= k && break
    end
    return bnz
end

@time bnz = find_nonzeroes(b, k);

# are results same?
println("Return arrays equal? ", isequal(bidx,bnz))

在我的机器上,运行两次后,结果是:

0.001795 seconds (10.03 k allocations: 158.402 KB)
0.004593 seconds (2.57 k allocations: 131.876 KB)
Return arrays equal? true

但是,如果你抬高b的维度,比如说p = 1000000,那么结果就完全不同了:

0.028236 seconds (1.00 M allocations: 15.261 MB, 7.70% gc time)
0.005493 seconds (2.57 k allocations: 131.876 KB)
Return arrays equal? true

find_nonzeores函数比find更复杂,更不灵活,但它可以更好地扩展到更高的p。在高维度上,权衡可能是值得的,特别是如果您经常在代码中调用find

由于您没有提供有关您移植到Julia的详细信息,因此很难为您提供更具体的建议。 performance tips上的Julia页面是我的首选参考,重新重新阅读它经常帮助我提高代码的速度。