Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/434.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使Java8Nashorn快速?_Java_Javascript_Performance_Nashorn - Fatal编程技术网

如何使Java8Nashorn快速?

如何使Java8Nashorn快速?,java,javascript,performance,nashorn,Java,Javascript,Performance,Nashorn,我使用Java8Nashorn渲染到HTML服务器端。如果我编译、缓存并重用编译脚本,则渲染某个页面需要5分钟。但是,如果我改为使用eval,缓存并重用脚本引擎,则渲染同一页面需要3秒钟 为什么CompiledScript这么慢?(示例代码如下) 在Nashorn中一次又一次地尽可能快地运行Javascript代码的好方法是什么?避免多次编译Javascript代码 这是服务器端Scala代码段,它以5分钟的时间调用Nashorn:(当运行200次时;我正在将许多注释从CommonMark编译为

我使用Java8Nashorn渲染到HTML服务器端。如果我编译、缓存并重用
编译脚本
,则渲染某个页面需要5分钟。但是,如果我改为使用
eval
,缓存并重用脚本引擎,则渲染同一页面需要3秒钟

为什么
CompiledScript
这么慢?(示例代码如下)

在Nashorn中一次又一次地尽可能快地运行Javascript代码的好方法是什么?避免多次编译Javascript代码

这是服务器端Scala代码段,它以5分钟的时间调用Nashorn:(当运行200次时;我正在将许多注释从CommonMark编译为HTML。)(此代码基于。)

编辑注意上面的
$script
被重新评估了200次。我确实测试了一个只评估过一次的版本,但很明显,后来我写了一些bug,因为只有一次的版本不会超过5分钟,尽管它应该是最快的版本之一。以下是快速版本:

...
val newCompiledScript = newEngine.asInstanceOf[js.Compilable].compile(s"""
  var global;
  var remarkable;
  if (!remarkable) {
    global = this;
    $script;
    remarkable = new Remarkable({});
  }
  remarkable.render(__source__);""")
...
/Edit

而这需要2.7秒:(运行200次时)

实际上,我猜
CompiledScript
版本(最上面的代码片段)会更快。无论如何,我想我必须缓存呈现的HTML服务器端

(Linux Mint 17和Java 8 u20)

更新:

我刚刚注意到,在末尾使用
invokeFunction
而不是
eval
的速度几乎是原来的两倍,只需1.7秒。这大概和我的Java7版本一样快,该版本使用Rhino编译的Javascript代码转换成Java字节码(作为构建过程中一个独立而复杂的步骤)。也许这是最快的速度了

if (engine == null) {
  engine = new js.ScriptEngineManager(null).getEngineByName("nashorn")
  engine.eval("var global = this;")
  engine.eval(new jio.FileReader("public/res/remarkable.min.js"))
  engine.eval("remarkable = new Remarkable({});")
  engine.eval(
    "function renderCommonMark(source) { return remarkable.render(source); }")
}
val htmlText = engine.asInstanceOf[js.Invocable].invokeFunction(
                                       "renderCommonMark", "**bold1**")

CompiledScript在8u40中有了一些改进。您可以下载jdk8u40@

的早期访问下载使用
CompiledScript
的代码变体似乎重新评估了
signific.min.js
200次,而基于
eval
的版本只执行一次。这解释了运行时的巨大差异


只需预先编译
引人注目的.render(
source),基于
CompiledScript
的变体比基于
eval
invokeffunction
的变体(在我的机器上,Oracle Java 8u25)稍微快一些。

我还发现nashorn比rhino慢。在温暖的JIT中速度会快得多,但在寒冷中速度却慢得无法忍受。同样好奇的是,你是否能对此做些什么。不过,这并不能真正回答问题。这似乎就是解释。我确实测试了一个替代方案,该方案没有多次重新评估
引人注目的.min.js
,但发现它也需要5分钟,因此我没有将其包括在问题中。然而,我一定犯了一些错误(即意外地将变量重置为null,而不是仅仅声明它),因为现在当我再次测试一个未重新评估
非凡.min.js的
编译脚本时,它的速度大致与fast
eval
版本一样快(不知道我的计算机上哪一个最快).我用fast
CompiledScript
版本更新了这个问题-我希望它与您使用的版本大致相同?我觉得有点不确定Nashorn在随后的
eval
调用后会记住哪些变量,但显然它确实会记住顶级变量,如
global
spective
。实际上,我只是预编译了
spective.render(\uu source\uuu)
。所有顶级脚本变量最终都在引擎范围内,并被每个
eval
重新使用(并最终修改),无论是否预编译。(我实际验证了在使用eval和预编译变量执行脚本后绑定是相等的。)
if (engine == null) {
  engine = new js.ScriptEngineManager(null).getEngineByName("nashorn")
  engine.eval("var global = this;")
  engine.eval(new jio.FileReader("public/res/remarkable.min.js"))
  engine.eval("remarkable = new Remarkable({});")
}
engine.put("source", "**bold**")
val htmlText = engine.eval("remarkable.render(source)")
if (engine == null) {
  engine = new js.ScriptEngineManager(null).getEngineByName("nashorn")
  engine.eval("var global = this;")
  engine.eval(new jio.FileReader("public/res/remarkable.min.js"))
  engine.eval("remarkable = new Remarkable({});")
  engine.eval(
    "function renderCommonMark(source) { return remarkable.render(source); }")
}
val htmlText = engine.asInstanceOf[js.Invocable].invokeFunction(
                                       "renderCommonMark", "**bold1**")