如何对 Raku 进行基准测试?

How to benchmark Raku?

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

我有时会看到提交中各个函数加速了一定百分比,时间如下图所示。

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

我阅读了生成 html 输出的帮助 here, here. I googled but could not find this information. I also learnt about MoarVM profiler via command line --profile option here。寻找什么?

我不是正式的计算机科学专业人士。 Tony Hoare — “Premature optimization is the root of all evil” 的名言我听懂了,但随着时间的推移,一旦代码写对了,人们就想优化它。所以问题。

我使用 --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