Experimental feature in GraalVM

报告性能问题

如果您发现 TruffleRuby 的性能低于其他 Ruby 实现,我们很乐意听取您的意见。请在 GitHub 上报告您可能发现的任何性能问题。

兼容性指南列出了一些我们已知速度较慢且不太可能变快的功能。

常见问题及原因 #

TruffleRuby 使用极其复杂的技术来优化您的 Ruby 程序。这些优化需要时间来应用,因此 TruffleRuby 在预热之前通常比其他实现慢很多。

此外,TruffleRuby 尝试找到您程序的“稳定状态”,然后自动删除 Ruby 中不必要的动态性,但这意味着如果稳定状态被扰乱,性能会再次下降,直到 TruffleRuby 适应新的稳定状态。

另一个问题是 TruffleRuby 非常擅长消除不必要的工作,例如不需要的计算或不包含任何工作的循环。

所有这些问题都使得对 TruffleRuby 进行基准测试变得困难。这不是我们独有的问题——它适用于许多复杂的虚拟机——但大多数 Ruby 实现尚未执行足够强大的优化来展示这些问题,因此它们对于 Ruby 社区中的一些人来说可能是新的。

使用 Oracle GraalVM #

要试验 TruffleRuby 的速度能有多快,请使用 Oracle GraalVM

使用 JVM 配置 #

为了获得最佳峰值性能,请使用 JVM 配置,即使用 --jvm。默认的本地配置启动更快,但无法达到相同的峰值性能。但是,您必须使用一个好的基准测试工具,例如下面描述的 benchmark-ips,来运行基准测试,否则较慢的预热时间将意味着您无法在基准测试中看到 TruffleRuby 的真实性能。如果您想编写更简单的基准测试,只用一个简单的计时器运行一个 while 循环(我们无论如何也不推荐这样做),那么请使用默认的本地模式,这样启动和预热时间会更短。

如何检查基本性能问题 #

如果您正在检查 TruffleRuby 的性能,我们建议您始终使用 --engine.TraceCompilation 标志运行。如果您看到编译失败或相同方法重复编译,这表明某些功能未能按预期工作,您可能需要检查原因,或请求我们帮助您这样做。如果您不使用此标志运行,TruffleRuby 将尝试解决错误,您将不会看到存在问题。

如何编写性能基准测试 #

TruffleRuby 团队建议您使用 benchmark-ips 来检查 TruffleRuby 的性能。如果您使用 benchmark-ips 的报告来报告任何潜在的性能问题,会使我们更容易处理。

一个基准测试可能看起来像这样

require 'benchmark/ips'

Benchmark.ips do |x|
  x.iterations = 2

  x.report("adding") do
    14 + 2
  end
end

我们使用 benchmark-ips 中的 x.iterations = 扩展来运行 benchmark-ips 的预热和测量循环两次,以确保结果稳定并提供了足够的预热(这可以通过 x.warmup = 5 进行调整)。

您应该看到类似这样的内容

Warming up --------------------------------------
              adding    20.933k i/100ms
              adding     1.764M i/100ms
Calculating -------------------------------------
              adding      2.037B (±12.7%) i/s -      9.590B in   4.965741s
              adding      2.062B (±11.5%) i/s -     10.123B in   4.989398s

我们想看最后一行,它表示 TruffleRuby 每秒运行 20.62 亿次此代码块,误差范围为 ±11.5%。

将其与 Rubinius 等实现进行比较

Warming up --------------------------------------
              adding    71.697k i/100ms
              adding    74.983k i/100ms
Calculating -------------------------------------
              adding      2.111M (±12.2%) i/s -     10.302M
              adding      2.126M (±10.6%) i/s -     10.452M

在这里,TruffleRuby 的性能可以描述为比 Rubinius 快一千倍。这看起来很多——这里实际发生的是 TruffleRuby 正在优化掉您的基准测试。对于无法优化掉的复杂代码,这种效果不那么明显。

最终技术说明:黑洞和值剖析 #

其他语言的一些基准测试工具具有名为“黑洞”的功能。它们围绕一个值,使其在运行时看起来像一个变量,即使它实际上是一个常量,这样优化器就不会将其移除并实际执行任何使用它的计算。然而,TruffleRuby 使用广泛的值剖析(值的缓存并将其转换为常量),因此即使您使一个值在其源头看起来像一个变量,它也可能在中间阶段被进行值剖析。一般来说,自然地击败值剖析的更复杂的基准测试是更优选的,而不是手动添加注释来关闭重要功能。

联系我们