java - 与 Java 7 相比,Java 8 ScriptEngine 的主要性能问题

标签 java performance java-8 scriptengine

我有一个 Java 程序(使用 JDK 7u80 编译),它广泛使用了“JavaScript”ScriptEngine (JSR-223)。我注意到,与 Java 7 运行时环境 (JRE 7u80) 相比,我的程序在 Java 8 运行时环境 (JRE 8u65) 下执行时运行速度极慢。

我整理了以下 SSCCE 来演示问题,然后在同一台 Windows PC 上的 Java 7 和 Java 8 下执行它:

import javax.script.*;

public class SSCCE {
  public SSCCE() {
    ScriptEngineManager sem = new ScriptEngineManager();
    ScriptEngine js = sem.getEngineByName("JavaScript");
    long t = 0;
    int i = 0;

    String gJs = "function ip2long(ip) {";
    gJs += "var aIP = ip.split(\".\");";
    gJs += "return (aIP[0] * Math.pow(256, 3)) + (aIP[1] * Math.pow(256, 2)) + (aIP[2] * 256) + (aIP[3] * 1);";
    gJs += "}";
    gJs += "function long2ip(l) {";
    gJs += "if (!isNaN(l) && ((l >= 0) || (l <= Math.pow(2, 32)))) {";
    gJs += "return Math.floor(l / Math.pow(256, 3)) + \".\" +";
    gJs += "Math.floor((l % Math.pow(256, 3)) / Math.pow(256, 2)) + \".\" +";
    gJs += "Math.floor(((l % Math.pow(256, 3)) % Math.pow(256, 2)) / Math.pow(256, 1)) + \".\" +";
    gJs += "Math.floor((((l % Math.pow(256, 3)) % Math.pow(256, 2)) % Math.pow(256, 1)) / Math.pow(256, 0));";
    gJs += "}";
    gJs += "return null;";
    gJs += "}";

    try {
      js.eval(gJs);
    }
    catch (Exception e) {
      e.printStackTrace();
    }

    System.out.println("Warming Up...");

    t = System.nanoTime();

    for (i = 0; i < 4097; i++) {
      try {
        String sJs = "var ip = \"192.0.2.0\";";
        sJs += "var nip = long2ip(ip2long(ip, " + i + "));";
        js.eval(sJs);
      }
      catch (Exception e) {
        e.printStackTrace();
      }
    }

    System.out.println("Starting...");

    t = System.nanoTime();

    for (i = 0; i < 4097; i++) {
      try {
        String sJs = "var ip = \"192.0.2.0\";";
        sJs += "var nip = long2ip(ip2long(ip, " + i + "));";
        js.eval(sJs);
      }
      catch (Exception e) {
        e.printStackTrace();
      }
    }

    System.out.println("Elapsed Time: " + (System.nanoTime() - t) / 1000000000.0f);
  }

  public static void main(String[] args) {
    new SSCCE();
  }
}

JavaScript 由一个函数组成,该函数将 IP 地址转换为长整数,添加一个数字,然后将其转换为 IP 地址 - 这重复了 4096 次。

我在 Java 7 和 Java 8 之间看到以下结果:

D:\Scripts>java7 SSCCE
Warming Up...
Starting...
Elapsed Time: 0.5856594

D:\Scripts>java8 SSCCE
Warming Up...
Starting...
Elapsed Time: 4.6862915

我应该将此作为与 Java 8 相关的性能错误提出吗?

更新:包括预热阶段以确保所有代码路径在我的计时循环之前都已初始化。

最佳答案

Java 8 改进了 JavaScript 引擎,如果使用 compile compiledScript 方式,就不用每次都重新评估源代码。使用eval方法,jdk8中使用的Hashorm引擎比jdk7中使用的Rhino慢,但更安全。

如果您追求速度,则更喜欢 StringBuffer 与 String 以及 Math.pow(2, 32) 和 Math.pow(256, 3) 值常量的使用...

你的

关于java - 与 Java 7 相比,Java 8 ScriptEngine 的主要性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33596023/

相关文章:

java写类到文件

Java:从日期获取月份整数

iPhone 性能测量只运行一次的代码?

c# - C# 存储大于 512 个长整型(4096 字节)的数组是否有所不同?

java - 具有相同根的类属性的 JAXB

java - 我在 if-else 循环中收到 java.util.EmptyStackException 。堆栈实现哪里出了问题?

python - 多维 numpy 数组中列表的频率表

java-8 - 如何从 Java8 的 spliterator 中的 tryAdvance 方法返回值?

java - 在 Java 8 中实现两个具有相同签名的默认方法的两个接口(interface)

java-8 - 收藏集与加入Java 8