Julia - 为什么循环更快?

4

我有MATLAB的背景,所以我倾向于将所有东西向量化。然而,在Julia中,我测试了这两个函数:

function testVec(n)
    t = [0 0 0 0];
    for i = 1:n
        for j = 1:4
            t[j] = i;
        end
    end
end

function testVec2(n)
    t = [0 0 0 0];
    for i = 1:n
        t.= [i i i i];
    end
end

@time testVec(10^4)
0.000029 seconds (6 allocations: 288 bytes)
@time testVec2(10^4)
0.000844 seconds (47.96 k allocations: 1.648 MiB)

我有两个问题:

  1. 为什么循环更快?
  2. 如果循环确实更快,那么是否有“智能”向量化技术可以模仿循环?循环的语法又丑又长。

1
离题:我是这里唯一一个觉得Matlab代码中充满了“聪明”的bsxfun向量化技巧实际上很难阅读的人吗?在某些情况下,我们只需要循环,这样应该会更快 ;) - Gnimuc
2个回答

5
  1. 在底层,一切都是循环。向量表达式在 Julia 和 Matlab 中都会被翻译为循环。最终一切都是循环。在您特定的示例中,正如 @sam 所说,因为您正在分配许多额外的数组,如果您明确循环,则可以避免这些数组。您在 Matlab 中仍然这样做的原因是,然后所有内容都被派到使用高性能语言(C 或 Fortran,可能)编写的函数中,因此即使进行额外的分配也值得。

  2. 确实有 broadcasting 和 loop fusion,就像 @sam 展示的那样。这里有一篇博客文章,告诉您关于 broadcasting 和 loop fusion 的所有需要了解的内容。


4
testVec2方法中,代码将为循环中每个i实例分配一个临时向量以容纳[i i i i]。这种分配并不是免费的。您可以在计时结果中打印的分配数量中看到这一点。您可以尝试以下操作:
function testVec3(n)
    t = [0 0 0 0]
    for i=1:n
        t .= i
    end
 end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接