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

2024-05-01

我有一个 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 相关的性能错误来提出吗?

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


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

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

Yours

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

与 Java 7 相比,Java 8 ScriptEngine 的主要性能问题 的相关文章

  • 在 Java 中将日期从 UTC 转换为 PST

    我需要将日期从 Google App Engine 本地服务器时区转换为 Java 中的太平洋时间 我尝试使用 Calendar calstart Calendar getInstance calstart setTimeZone Time
  • Eclipse 调试“未找到源”

    我刚刚开始使用 Eclipse 所以慢慢来吧 但是 当尝试调试 JUnit 测试用例时 我会收到一个对话框 指出当我在测试方法中的代码中找到此行时 未找到源代码 Assert assertEquals 1 contents size 我知道
  • 在java中查找OSX的版本

    我需要测试 java 中 osx 的版本是否 Try System getProperty os name and or System getProperty os version 它返回字符串 HERE https docs oracle
  • Android 上 WebRTC 的自定义视频源

    Overview 我想使用自定义视频源通过 WebRTC Android 实现来直播视频 如果我理解正确的话 现有的实现仅支持 Android 手机上的前置和后置摄像头 以下类与此场景相关 Camera1Enumerator java ht
  • [重复]

    这个问题在这里已经有答案了 有什么区别List
  • Play Framework 2.5.1 路由和依赖项注入(适用于 Java)

    我的 路线 文件中有这个 POST accounts controllers AccountsController createOneAccount 在我的 AccoutsController java 中 package controll
  • 快速检查网络速度

    我想从我的 swift 应用程序检查网络速度 我发现很多帖子描述了Reachability特别是查找连接是否可达以及是 WIFI 连接还是 WWAN 连接的方法 我的问题 是否可以检测 WWAN 的类型 2G 3G 4G 你可以用以下命令检
  • 节省页面加载时间的提示[重复]

    这个问题在这里已经有答案了 我的问题 削减那些不必要的 kb 并使页面加载速度更快的最佳方法是什么 全部是什么优化实践 编码实践 在js php中 如果执行可以使您的页面更轻 为什么我问这个 我读了这篇关于 jquery js 与 jque
  • 阻止 GWT 中的事件冒泡

    我有以下代码片段 changeTextArea 是一个 TextArea 对象 changeTextArea addKeyboardListener new KeyboardListenerAdapter public void onKey
  • 我可以直接在 Maven 中使用 GitHub 项目吗?

    我有兴趣使用GitHub 上的项目 https github com toelen spymemcached jcache作为我的项目中的依赖项 GitHub 项目有一个pom文件 我可以修改我的pom文件来使用这个项目 如果是这样 怎么办
  • 如何在调整大小时更改 JLabel 字体大小以填充 JPanel 可用空间?

    这里有一个类似的问题 如何更改 JLabel 的字体大小以获取最大大小 https stackoverflow com questions 2715118 how to change the size of the font of a jl
  • 优化两个三位数乘积的最大回文数?

    我正在研究一个面试问题 我被问到这个问题 我应该编写一个程序 从两个三位数的乘积中找到最大的回文数 这里是question https projecteuler net problem 4 我想出了这种从底部开始的蛮力方法 public c
  • 计算事件之间的天数 - Android

    我一直在研究 Android API 并一直在寻找一种方法来计算当前日期和未来日期之间的天数 我对 android 还很陌生 而且我已经有几年没有做过 java 了 计算这个最简单的方法是什么 Thanks 最简单的方法是使用乔达时间 ht
  • 部署到 Glassfish 4.1 时 URL 模式无效

    如果用户已经通过身份验证 我有一个网络过滤器可以从登录和索引页面重定向 最初我有一个无效的 URL 模式 我修复了无效模式并尝试重新部署以接收以下内容 java lang IllegalArgumentException Invalid U
  • JPA中如何连接多个数据库?

    我有一个 Spring Boot 应用程序 当前使用 JPA 连接到单个数据库 application properties 文件中的连接详细信息 spring datasource url jdbc oracle thin localho
  • startDrag 方法 已弃用且无法编译程序

    startDrag android content ClipData android view View DragShadowBuilder java lang Object int 已弃用 如何解决这个问题而又不失去对旧版本的兼容性 还有
  • 有没有办法让 SonarQube 只警告不完整的 Switch 语句?

    使用 Java SonarQube 抱怨枚举值上的 switch 语句没有default case 给出的推理是 最终默认条款的要求是防御性编程 该条款应采取适当的行动 或包含 关于为什么不采取行动的适当评论 当开关盖上时 枚举的所有当前值
  • 运行外部进程的非阻塞线程

    我创建了一个 Java GUI 应用程序 它充当许多低级外部进程的包装器 该实用程序按原样运行 但迫切需要一项重大改进 我希望我的外部进程以非阻塞方式运行 这将允许我并行服务其他请求 简而言之 我希望能够在生成数据时处理来自外部进程的数据
  • 在 unix 中编译 dhrystone 时出错

    我是使用基准测试和 makefile 的新手 我已经从下面的链接下载了 Dhrystone 基准测试 我正在尝试编译它 但我遇到了奇怪的错误 我尝试解决它 但没有成功 有人可以帮助我运行 dhrystone 基准测试吗 以下是我尝试编译的两
  • 切换按钮形状不变

    我正在尝试制作一个带有绿色背景的圆形切换按钮 我用了

随机推荐