使用Julia的内置功能时性能降低 [英] Performance slowdown when using Julia's built-in functions

查看:88
本文介绍了使用Julia的内置功能时性能降低的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我所属的一个研究小组最近决定尝试从我们以前的编码语言迁移到Julia,因为除其他因素外,与其他用户友好语言相比,该语言声称具有高速性能.但是,在我们的代码片段的初始翻译中,我的一位合作伙伴注意到与使用简单的循环技术相比,使用Julia的内置函数(特别是诸如"find"之类的相当简单的函数)会导致速度降低大约十倍.有没有其他人遇到过这个问题,或者还有其他可能的原因值得我们研究吗?

A research group I am a part of has recently decided to try migrating to Julia from our previous coding language, because of, among other things, its claimed high-speed performance as compared to other user-friendly languages. However, in our initial translations of code snippets, one of my partners noticed that using Julia's built-in functions (specifically rather simple ones such as 'find') causes about a tenfold drop in speed as compared to using simple looping techniques. Has anyone else encountered this, or are there other probable causes we should look into?

推荐答案

请原谅我的评论,因为我缺少代表来发表适当的评论...

Pardon the comment-for-an-answer, since I lack the rep to do a proper comment...

我对Julia的了解是,如果您为了获得最佳性能而钓鱼,通常最好编写循环.这已经有一段时间了.请参见林大华的有关对向量进行向量化的帖子. (,但将来可能会改变;请参阅Colin T. Bowers关于多线程的讨论

What I understand about Julia is that it is usually better to write loops if you are fishing for maximum performance. This has been true for quite a while; see, e.g., Dahua Lin's post about devectorizing expressions. (edit: but it may change in the future; see Colin T. Bowers' discussion about multithreading here and in comment below).

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

Keep in mind that judging performance can be tricky. I actually use find a lot in my own code since I can succinctly ask for the Int indices of the nonzeroes in a "sparse" Vector that is not obscenely long. find is relatively flexible, speedy, and clear compared to an equivalent loop. For example:

# 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))

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

On my machine, after running everything twice, the results are:

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说,那么结果会大不相同:

But if you jack up the dimension of b, say to p = 1000000, then the results are quite different:

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时.

The find_nonzeores function is more convoluted and less flexible than find, but it scales better to higher p. In high dimensions the tradeoff may be worth it, especially if you often call find in your code.

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

Since you offer no details about what you ported to Julia, then it is difficult to offer you any more specific advice than that. The Julia page on performance tips is my go-to reference, and re-re-re-reading it has often helped me improve my code's speed.

这篇关于使用Julia的内置功能时性能降低的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆