【问题标题】:How to benchmark Raku?如何对 Raku 进行基准测试?
【发布时间】:2020-05-14 07:18:19
【问题描述】:

我会定期关注GitHub Rakudo repository,以查看 Rakudo 编译器发生了哪些变化。

我有时会看到单个函数以一定百分比加速的提交,以及如下图所示的时间。

评估这个的工作流程是什么?我很想了解这一点,以便人们可以了解您的功能如何执行并相应地进一步优化并为 Rakudo 开发做出贡献。

我阅读了herehere 的帮助。我用谷歌搜索但找不到此信息。我还通过命令行--profile 选项here 了解了MoarVM 分析器,该选项生成html 输出。它要寻找什么?

我不是一个正式的计算机科学专家。我了解Tony Hoare — “Premature optimization is the root of all evil” 的名言,但随着时间的推移,一旦代码编写正确,人们希望对其进行优化。那么问题来了。

【问题讨论】:

  • 托尼·霍尔:奥卡姆人!对吗?

标签: benchmarking raku rakudo


【解决方案1】:

我使用--profile 来更好地了解瓶颈所在。生成的配置文件是一个好的开始,但当差异变得非常小时,对 CPU 使用率不是很好。然而,它非常擅长跟踪对象的分配,并且更少的对象分配至少可以意味着更少的内存流失(但并非总是如此,如果对象非常是短暂的)。并且使用--profile 跟踪内容也会对优化产生影响,因此海森堡的不确定性原理在这里绝对适用。

一旦我有了一段之前/之后的代码,我就可以将其作为脚本运行,也可以作为带有time 的单行代码运行。我有一堆方便的别名可以帮助我:

alias r='time raku -e'
alias rp='raku --profile -e'

我将其作为单独的进程执行,中间至少间隔几秒钟的原因是:

  1. 在此过程中运行多个基准测试往往会导致 CPU 升温,然后会降速,使后面的基准测试变得更糟。
  2. 如果两个基准测试共享核心中的某些代码,则后面的基准测试可能会受益于该代码已被早期基准测试内联/JIT。

然后我将之前和之后的代码分别运行 3 到 5 次,并使用 Nil 循环找出开销。例如:

$ r 'my $a = "42"; Int($a) for ^100000'
real    0m0.244s

$ r 'my $a = "42"; $a.Int for ^100000'
real    0m0.178s

$ r 'my $a = "42"; Nil for ^100000'
real    0m0.154s

然后计算差值:

$ r 'say (244 - 154) / (178 - 154)'
3.75

因此,使用 $a.Int 的速度大约是使用 Int($a) 的 3.75 倍。这当然可以开始另一个--profile 循环,找出为什么Int($a) 这么慢。此外,当我看到我无法解释的速度差异时,我使用--profile 来确定它是否真的在做我认为它正在做的事情。特别是出乎意料的常量折叠有时会让您认为您找到了最佳优化,而实际上您将代码减少到基本上什么都不做。

HTH

【讨论】:

  • 感谢您的详细解答。
  • 只是补充一下@elizabeth-mattijsen 所说的内容,我经常发现测量代码的挂钟时间并消除启动/预编译时间很有帮助。我通过添加say now - ENTER now 作为我要测量的任何块的最后一行来做到这一点。 ENTER now 由块开始处的 ENTER 移相器运行。
  • 同理,给别人看或者在#rakum:上粘贴,可以做END say now - INIT now,也就是当程序完成时,显示当时和执行时的时间差主线的启动。
猜你喜欢
  • 2023-03-13
  • 1970-01-01
  • 2012-02-02
  • 1970-01-01
  • 2013-05-30
  • 2010-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多