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

时间:2013-10-06 10:49:36

标签: benchmarking octave julia

关注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。

2 个答案:

答案 0 :(得分:62)

.^这样的矢量化操作正是Octave擅长的那种,因为它们实际上完全是在专门的C代码中实现的。在构建Octave时编译的代码中的某个地方,有一个C函数可以计算.^的双精度数和一个双精度数组 - 这就是你真正在这里计时的时间,并且它很快,因为它是用C语言编写的另一方面,朱莉娅的.^算子是用朱莉娅写的:

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中,即使是索引到数组或添加两个整数等基本内容实际上也是方法调用,因此离开了当前范围。但是,在这个问题的代码中,所有时间都花在.^函数中,因此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

答案 1 :(得分:14)

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

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

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