Nashorn 在 JDK 9 和 JDK 10 上的性能表现

16
如果你在JDK 8上使用Nashorn解释moment.js库,它只需要几秒钟就能运行:

time .../JDK8/bin/jjs moment-with-locales-2.22.2.js
real    0m2.644s
user    0m10.059s
sys     0m0.287s

但是在JDK 9或10上进行相同的操作,速度非常慢:

time .../JDK10/bin/jjs moment-with-locales-2.22.2.js
real    0m27.308s
user    0m59.690s
sys     0m1.353s

这是慢了十倍。这只是我的问题吗?

我知道Nashorn即将被弃用,但是在其受支持期间,它不应该正常工作吗?

有什么建议?解决方法吗?

1个回答

15

Nashorn可以使用“乐观类型”(下文将详细介绍),在Java 9及更高版本中默认启用,但会导致启动时出现延迟。

关闭乐观类型将产生以下结果:

$ time jjs --optimistic-types=false moment-with-locales.js
real    0m4.282s
user    0m0.000s
sys     0m0.015s

开关可以缩写为-ot=false

jjs -h将乐观类型定义如下:

使用具有去优化重新编译的乐观类型假设。这使得编译器尝试将无法在编译时证明其类型的任何程序符号类型化为最窄和原始的类型。如果运行时因符号类型太窄而遇到错误,则将生成更宽的方法,直到达到稳定阶段。虽然这会产生尽可能优化的Java字节码,但错误的类型猜测会导致较长的热身时间。乐观类型目前默认启用,但可以禁用以提高启动性能。

因此,乐观类型在长期内可能会产生更快的性能(尽管不能保证),但会导致启动变慢。


非常有趣 - 感谢您的指示。我仍然有点震惊存在如此大的差异,但更多的测试确实证实这只是在启动时发生。如果您一遍又一遍地执行相同的JS代码,则只需要支付一次代价,但这是一个沉重的代价!我猜moment.js的编译非常昂贵,因为它必须经过多次重新编译。它并不是很大(~50K),所以对于更大的JS库来说前景不太乐观。 - Max Tardiveau
1
跟进一下--我们现在通过以下方式默认禁用乐观类型优化:jsEngine = nashornEngineFactory.getScriptEngine(new String[] { "--optimistic-types=false" });这使我们的启动时间更加符合JDK 8,但代价是减少了优化。再次感谢您的帮助! - Max Tardiveau
@MaxTardiveau 如果我的回答有帮助并回答了您的问题,您可以接受它。 - David Conrad

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