朱莉娅语言真的如它声称的那样快吗? [英] Is the Julia language really as fast as it claims?

查看:104
本文介绍了朱莉娅语言真的如它声称的那样快吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这篇文章之后我决定对Julia进行GNU Octave基准测试,结果与 julialang.org 中说明的提速操作.

Following this post I decided to benchmark Julia against GNU Octave and the results were inconsistent with the speed-ups illustrated in julialang.org.

我用CXXFLAGS='-std=c++11 -O3'编译了Julia和GNU Octave,得到的结果是:

I compiled both Julia and GNU Octave with CXXFLAGS='-std=c++11 -O3', the results I got:

a=0.9999;

tic;y=a.^(1:10000);toc
Elapsed time is 0.000159025 seconds.

tic;y=a.^(1:10000);toc
Elapsed time is 0.000162125 seconds.

tic;y=a.^(1:10000);toc
Elapsed time is 0.000159979 seconds.

-

tic;y=cumprod(ones(1,10000)*a);toc
Elapsed time is 0.000280142 seconds.

tic;y=cumprod(ones(1,10000)*a);toc
Elapsed time is 0.000280142 seconds.

tic;y=cumprod(ones(1,10000)*a);toc
Elapsed time is 0.000277996 seconds.

朱莉娅

tic();y=a.^(1:10000);toc()
elapsed time: 0.003486508 seconds

tic();y=a.^(1:10000);toc()
elapsed time: 0.003909662 seconds

tic();y=a.^(1:10000);toc()
elapsed time: 0.003465313 seconds

-

tic();y=cumprod(ones(1,10000)*a);toc()
elapsed time: 0.001692931 seconds

tic();y=cumprod(ones(1,10000)*a);toc()
elapsed time: 0.001690245 seconds

tic();y=cumprod(ones(1,10000)*a);toc()
elapsed time: 0.001689241 seconds

有人可以解释为什么在这些基本操作中Julia比GNU Octave慢吗?加热后,它应该在没有开销的情况下调用LAPACK/BLAS,对吗?

Could someone explain why Julia is slower than GNU Octave with these basic operations? After warmed, it should call LAPACK/BLAS without overhead, right?

如评论和答案中所述,上面的代码不是一个好的基准,也不能说明在实际应用程序中使用该语言的好处.我曾经把Julia看作是更快的"Octave/MATLAB",但远不止于此.这是朝着生产,高性能,科学计算迈出的巨大一步.通过使用Julia,我能够(1)在我的研究领域中以Fortran和C ++编写的软件跑赢软件,并且2)为用户提供更好的API.

As explained in the comments and answers, the code above is not a good benchmark nor it illustrates the benefits of using the language in a real application. I used to think of Julia as a faster "Octave/MATLAB", but it is much more than that. It is a huge step towards productive, high-performance, scientific computing. By using Julia, I was able to 1) outperform software in my research field written in Fortran and C++, and 2) provide users with a much nicer API.

推荐答案

.^这样的矢量化操作正是Octave擅长的事情,因为它们实际上完全用专用的C代码实现.生成Octave时在编译的代码中的某个地方,有一个C函数可以计算.^来生成一个double和一个double数组-这就是您真正在这里计时的时间,并且它很快,因为它是用C编写的.另一方面,.^运算符是用Julia编写的:

Vectorized operations like .^ are exactly the kind of thing that Octave is good at because they're actually entirely implemented in specialized C code. Somewhere in the code that is compiled when Octave is built, there is a C function that computes .^ for a double and an array of doubles – that's what you're really timing here, and it's fast because it's written in C. Julia's .^ operator, on the other hand, is written in Julia:

julia> a = 0.9999;

julia> @which a.^(1:10000)
.^(x::Number,r::Ranges{T}) at range.jl:327

该定义包括以下内容:

.^(x::Number, r::Ranges) = [ x^y for y=r ]

它使用一维数组理解将x提升到r范围内的每个值y,并将结果作为向量返回.

It uses a one-dimensional array comprehension to raise x to each value y in the range r, returning the result as a vector.

爱德华·加森(Edward Garson)的观点很正确,那就是不应使用全局变量来获得朱莉娅的最佳表现.原因是编译器不能很好地考虑全局类型,因为全局类型可以在执行离开当前作用域的任何时候改变.离开当前作用域听起来并不经常发生,但是在Julia中,即使是索引到数组或添加两个整数之类的基本操作实际上也是方法调用,因此会离开当前作用域.但是,在此问题的代码中,所有时间都花在了.^函数内部,因此a是全局变量这一事实实际上并不重要:

Edward Garson is quite right that one shouldn't use globals for optimal performance in Julia. The reason is that the compiler can't reason very well about the types of globals because they can change at any point where execution leaves the current scope. Leaving the current scope doesn't sound like it happens that often, but in Julia, even basic things like indexing into an array or adding two integers are actually method calls and thus leave the current scope. In the code in this question, however, all the time is spent inside the .^ function, so the fact that a is a global doesn't actually matter:

julia> @elapsed a.^(1:10000)
0.000809698

julia> let a = 0.9999;
         @elapsed a.^(1:10000)
       end
0.000804208

最终,如果您所要做的只是在浮点数组上调用矢量化运算,那么Octave就可以了.但是,即使在高级动态语言中,通常也不会花费大部分时间.如果您发现自己想通过for循环遍历数组,并使用标量运算对每个元素进行操作,您会发现Octave在这种情况下非常慢-通常比C或Julia代码的执行速度慢数千倍同样的事情.另一方面,用Julia编写for循环是一件完全合理的事情–实际上,我们所有的排序代码都是用Julia编写的,并且在性能上可与C媲美.还有其他许多使用Julia的原因,它们与性能无关.作为Matlab的克隆,Octave继承了Matlab的许多设计问题,并且不能很好地用作通用编程语言.例如,您不想使用Octave或Matlab编写Web服务,但这是

Ultimately, if all you're ever doing is calling vectorized operations on floating point arrays, Octave is just fine. However, this is often not actually where most of the time is spent even in high-level dynamic languages. If you ever find yourself wanting to iterate over an array with a for loop, operating on each element with scalar arithmetic, you'll find that Octave is quite slow at that sort of thing – often thousands of times slower than C or Julia code doing the same thing. Writing for loops in Julia, on the other hand, is a perfectly reasonable thing to do – in fact, all our sorting code is written in Julia and is comparable to C in performance. There are also many other reasons to use Julia that don't have to do with performance. As a Matlab clone, Octave inherits many of Matlab's design problems, and doesn't fare very well as a general purpose programming language. You wouldn't, for example, want to write a web service in Octave or Matlab, but it's quite easy to do so in Julia.

这篇关于朱莉娅语言真的如它声称的那样快吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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