关于Julia和Matlab之间时序比较的奇怪观察

时间:2015-04-29 01:00:56

标签: 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
>> 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默认处理大数字算术运算。现在,看起来这些都不正确。有人可以解释一下吗?

1 个答案:

答案 0 :(得分:8)

这里有几件事情。

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

你需要做任何一次

x = 1.0:t*n

或通过

明确转换
x = float(x)

这也是答案不同的原因:Julia使用机器算术,对于整数将在溢出时回绕(因此为负数)。浮点值不会出现此问题。

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

这会让你加速,但你可以做得更好。 Julia确实需要与Matlab略有不同的编程风格。请参阅以上评论中Isaiah提供的链接。

关于您的具体示例

sum(x[:].* x[:])

这很慢,因为它创建了3个中间向量(x[:]的2个副本,但希望将来会改变它们的产品)。

同样,

trace(x*x')

计算中间矩阵(其中大部分未在跟踪中使用)。

我的建议是使用

dot(vec(x),vec(x))

vec(x)只需将x重新整形为一个向量(因此不需要复制),而dot是通常的总和产品。你也可以“自己动手”:

function test(x)
    s = zero(eltype(x)) # this prevents type-instability
    for xi in x
        s += xi*xi
    end
    s
end

test(x)

(这需要在JIT编译器的功能中发挥作用)。它应该相当快,但可能仍然不如dot快,它使用下面的BLAS调用。