首页 > 解决方案 > nashorn CompiledScript graalvm 等效

问题描述

我有一个相当大的文件需要经常评估,

与 nashorn 我曾经做过类似的事情:

CompiledScript compiledScript = ((Compilable) engine).compile(text);

后来,我可以多次拨打以下电话:

Context context = new SimpleScriptContext();
compiledScript.eval(context);

这是相当快的。

使用新的 Polyglot API,我这样做:

Source source = Source.newBuilder("js", myFile).build();

然后 :

Context context = Context.newBuilder("js").option("js.nashorn-compat", "true").build();
context.eval(source)

使用jmh,我两者之间的性能差异很大

Benchmark                     Mode  Cnt   Score    Error  Units
JmhBenchmark.testEvalGraal    avgt    5  42,855 ± 11,118  ms/op
JmhBenchmark.testEvalNashorn  avgt    5   2,739 ±  1,101  ms/op

如果我eval在相同的上下文中执行此操作,它可以正常工作,但我不想在两个连续的上下文之间共享上下文eval(除非 Graal 上下文的概念与 Nashorn 的上下文不同)。

标签: graalvm

解决方案


要使用 GraalVM 重现您的ScriptEngine设置,您应该重新使用相同的Engine( org.graalvm.polyglot.Engine) 和.close()使用后的上下文:

Source source = Source.newBuilder("js", myFile).build();
Engine engine = Engine.create();

然后:

Context context = Context.newBuilder("js")
                         .engine(engine)
                         .option("js.nashorn-compat", "true").build();
context.eval(source);
context.close();

引用Context.Builder.engine 文档

显式设置要使用的底层引擎。默认情况下,每个上下文都有自己的独立引擎。如果从一个引擎创建多个上下文,则它们可以通过指定单个底层引擎来共享/缓存某些系统资源,例如 AST 或优化代码。


推荐阅读