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