Julia语言真的和它声称的一样快吗?

问题描述 投票:40回答:2

this post之后,我决定将Julia与GNU Octave进行比较,结果与julialang.org中说明的加速度不一致。

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

GNU Octave

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,对吧?

编辑:

正如评论和答案中所解释的,上面的代码不是一个好的基准,也没有说明在实际应用程序中使用该语言的好处。我曾经认为Julia是一个更快的“Octave / MATLAB”,但它远不止于此。这是迈向高效,高性能,科学计算的重要一步。通过使用Julia,我能够1)在我用Fortran和C ++编写的研究领域中胜过软件,2)为用户提供更好的API。

benchmarking octave julia
2个回答
62
投票

.^这样的矢量化操作正是Octave擅长的那种,因为它们实际上完全是用专门的C代码实现的。在构建Octave时编译的代码中的某处,有一个C函数可以计算.^的双精度和双精度数组 - 这就是你在这里真正的计时,并且它很快,因为它是用C. 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提升到y范围内的每个值r,将结果作为向量返回。

Edward Garson非常正确,不应该使用全局变量来获得Julia的最佳表现。原因是编译器无法很好地推断全局变量的类型,因为它们可以在执行离开当前范围的任何时候进行更改。离开当前范围听起来并不常见,但在Julia中,即使是索引到数组或添加两个整数等基本内容实际上也是方法调用,因此离开了当前范围。但是,在这个问题的代码中,所有的时间都花在了.^函数中,所以a是一个全局的事实并不重要:

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服务,但在Julia中这样做是为了quite easy


14
投票

你正在使用全局变量,这是朱莉娅的性能问题。

问题是只要你的代码调用了anther函数,全局变量就可以改变类型。因此,编译器必须生成极其缓慢的代码,这些代码无法对所使用的全局变量类型做出任何假设。

根据https://docs.julialang.org/en/stable/manual/performance-tips/对代码进行简单修改可以产生更令人满意的结果。

© www.soinside.com 2019 - 2024. All rights reserved.