Performance Julia与Matlab定时比较的奇怪观察

Performance Julia与Matlab定时比较的奇怪观察,performance,matlab,julia,Performance,Matlab,Julia,这个实验的目的是用下面的一小段代码来比较Matlab和Julia的速度 首先是Matlab代码: >> t = 5000; n = 10000; x = 1:t*n; >> x = reshape(x, t, n); >> tic(); y1 = sum(x(:) .* x(:)); toc() Elapsed time is 0.229563 seconds. >> y1 y1 = 4.1667e+22 >&g

这个实验的目的是用下面的一小段代码来比较Matlab和Julia的速度

首先是Matlab代码:

>> t = 5000; n = 10000;  x = 1:t*n;
>> x = reshape(x, t, n);
>> tic(); y1 = sum(x(:) .* x(:)); toc()
Elapsed time is 0.229563 seconds.
>> y1

    y1 =
         4.1667e+22
>> tic(); y2 = trace(x * x'); toc()
Elapsed time is 15.332694 seconds.

>> y2
y2 =
       4.1667e+22
茱莉亚对决

julia> t = 5000; n = 10000; x = 1: t*n;    
julia> x = reshape(x, t, n);
julia> tic(); y1 = sum(x[:].* x[:]); toc();
elapsed time: 1.235170533 seconds
julia> y1
-4526945843202100544
julia> tic();y2 = trace(x*x'); toc();

第二个没有在超过1分钟内完成任务。朱莉娅怎么了?这段代码恰好在Julia中运行得较慢且溢出?我的风格有什么问题吗?我认为从Matlab转换到Julia的一个原因是速度,我过去认为Julia默认处理大数算术运算。现在看来这些都不正确。有人能解释一下吗?

这里发生了几件事

首先,与Matlab不同,
x
是一个机器整数数组,而不是浮点值。这似乎是速度上的主要差异,因为它无法将BLAS例程用于线性代数

你也需要这样做

x = 1.0:t*n
或者通过

x = float(x)
这也是一个不同答案的原因:Julia使用机器算法,对于整数,它将在溢出时环绕(因此为负数)。浮点值不会有这个问题

(Julia确实有任意精度的整数,但默认情况下不升级:相反,您需要通过
big(n)
自己升级它们)

这将给你一些速度,但你可以做得更好。Julia确实需要与Matlab稍有不同的编程风格。参见以上评论中以赛亚提供的链接

关于你的具体例子

sum(x[:].* x[:])
这是缓慢的,因为它创建了3个中间向量(2份
x[:]
,尽管希望这将在将来改变,以及它们的产品)

同样地

trace(x*x')
计算一个中间矩阵(其中大部分未在跟踪中使用)

我的建议是使用

dot(vec(x),vec(x))
vec(x)
只需将
x
重塑为一个向量(因此无需复制),而
dot
是常用的和积。你也可以“自己滚”:


(这需要在JIT编译器的函数中才能发挥作用)。它应该是相当快的,尽管可能还没有
dot
快,dot在下面使用BLAS调用。

看,这是一个很棒的答案。非常感谢西蒙·伯恩!回答得很好,但我希望你能选择时间。
function test(x)
    s = zero(eltype(x)) # this prevents type-instability
    for xi in x
        s += xi*xi
    end
    s
end

test(x)