【问题标题】:Why Julia is slower than MATLAB?为什么 Julia 比 MATLAB 慢?
【发布时间】:2020-11-27 09:46:01
【问题描述】:

我刚刚编写了这个非常简单的函数来测试 Julia 和 MATLAB 的性能。我刚刚注意到 MATLAB 的执行时间明显缩短。这是简单的代码:

MATLAB:

tic

aa = 0;

for loop =1:1e6

       aa = aa+loop;

end

toc

经过的时间是 0.004628 秒。

朱莉娅:

function sum_test(a)

    for i = 1:1e6
        a = a + i
    end

    return a
end

经过的时间是 0.093886155s:93 毫秒。

我还在 Julia 中编写了一个函数来避免使用全局变量,这提高了性能,但它仍然比 MATLAB 慢得多。有人可以帮我理解一下吗?

【问题讨论】:

  • 这么短的基准毫无意义。它至少应该运行几秒钟。也可以考虑使用scilab

标签: julia


【解决方案1】:

如果不了解您是如何为 Julia 代码计时的,就不可能说出来。然而,最可能的解释是您正在计时编译时间和执行时间。 Julia 和 MatLab 编译器的行为完全不同。当你在 Julia 中编写一个新函数时,它会在你第一次使用它时被编译。因此,它的第一次执行会很慢,但所有后续调用都很快。为了解决这个问题,如果您对 Julia 进行基准测试,建议您使用 BenchmarkTools 包。在我的(不是特别特别的)机器上:

function sum_test(a)
    for i = 1:1e6
        a = a + i
    end
    return a
end
using BenchmarkTools
@btime sum_test(1)

产生以下输出:

julia> @btime sum_test(1)
  2.135 ms (0 allocations: 0 bytes)

大约 2 毫秒,大约是 MatLab 运行速度的两倍。

但是我们可以做得更好吗?我们当然可以。 MatLab 倾向于将所有数字视为双精度浮点数,因此在 MatLab 中编码时不会过多考虑数字的类型。在 Julia 中,情况并非如此。在此示例中,您已将循环的上限指定为 1e6。请注意:

julia> typeof(1e6)
Float64

啊哈!您可能不希望循环变量是Float64,而是希望它是一个整数。那么当我们改变它时会发生什么?尝试运行:

function sum_test(a)
    for i = 1:1000000
        a = a + i
    end
    return a
end
using BenchmarkTools
@btime sum_test(1)

现在输出:

julia> @btime sum_test(1)
  1.208 ns (0 allocations: 0 bytes)

是的,您没看错。耗时 1.2 纳秒,比 MatLab 快大约 6 个数量级。

那么发生了什么?在循环上限是整数的情况下,Julia 编译器足够聪明地意识到它实际上并不需要运行循环来正确计算结果。由于正在执行的算法的性质,可以使用编译器为您完成的单个公式确定答案。换句话说,Julia 编译器优化了整个循环!

【讨论】:

  • 哈,@code_llvm sum_test(1)%1 = add i64 %0, 500000500000; ret i64 %1。这太棒了。
  • 我按照你的建议做了,我能够产生相同的结果,但它对我提出了一些其他问题: 1. 我使用以下方法来测量经过的时间:tick() Sum_test( 1) tock 这给了我这个:[信息:0.083350786s:83毫秒那么为什么使用@bitme和tick-tock来测量时间是不同的?而在我需要测量一段代码的运行时间的情况下,我该怎么办?
  • 2.我注意到,当我使用 btime 时,需要几秒钟(!!)来显示输出:3.176 毫秒(1 个分配:16 字节)。然后它不会给你感觉执行时间是毫秒级的。我问这个是因为我想报告我的代码的测量时间,我不确定使用 btime 是否可以在人们运行我的代码后说服他们。 3. 我注意到您的输出与我的不同,因为您报告(0 分配:0 字节)但我得到(1 分配:16 字节),为什么?
  • @btime 多次运行您的函数(可能数千次),并计算统计数据。 tic/toc 不适合测量非常短的函数的执行时间,因为测量结果会非常嘈杂,还可能包括编译时间、偶尔的操作系统中断或垃圾收集。所以不要使用tic/toc@time来衡量短函数的执行时间,使用@btime@benchmark。 Matlab 和 Python 相同:不要使用tic/toc,使用timeit 函数,类似于@btime
  • @NoseKnowsAll 我不是BenchmarkTools 的开发人员,但我之前在更长的例程中使用过@btime,而且它似乎仍然运行了很多次例程。换句话说,如果您在 2 分钟的例行程序中使用它,您可能要等待一段时间才能获得结果,尽管传闻可能只是几分钟,而不是几个小时。
猜你喜欢
  • 2012-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-23
  • 1970-01-01
  • 1970-01-01
  • 2015-12-18
  • 2013-08-08
相关资源
最近更新 更多