运行JDK代码时Java JIT会作弊吗?

2024-04-06

我正在对一些代码进行基准测试,但我无法让它运行得像java.math.BigInteger https://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html,即使使用完全相同的算法。 所以我复制了java.math.BigInteger https://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html源到我自己的包并尝试了这个:

//import java.math.BigInteger;

public class MultiplyTest {
    public static void main(String[] args) {
        Random r = new Random(1);
        long tm = 0, count = 0,result=0;
        for (int i = 0; i < 400000; i++) {
            int s1 = 400, s2 = 400;
            BigInteger a = new BigInteger(s1 * 8, r), b = new BigInteger(s2 * 8, r);
            long tm1 = System.nanoTime();
            BigInteger c = a.multiply(b);
            if (i > 100000) {
                tm += System.nanoTime() - tm1;
                count++;
            }
            result+=c.bitLength();
        }
        System.out.println((tm / count) + "nsec/mul");
        System.out.println(result); 
    }
}

当我运行这个(MacOS 上的 jdk 1.8.0_144-b01)时,它输出:

12089nsec/mul
2559044166

当我在导入行未注释的情况下运行它时:

4098nsec/mul
2559044166

使用 JDK 版本的 BigInteger 时,速度几乎是我的版本的三倍,即使它使用完全相同的代码。

我使用 javap 检查了字节码,并比较了使用选项运行时的编译器输出:

-Xbatch -XX:-TieredCompilation -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions 
-XX:+PrintInlining -XX:CICompilerCount=1

并且两个版本似乎生成相同的代码。 那么热点是否使用了一些我无法在代码中使用的预先计算的优化?我一直明白他们没有。 如何解释这种差异?


是的,HotSpot JVM 有点“作弊”,因为它有一些特殊版本BigIntegerJava 代码中找不到的方法。这些方法称为JVM 内在函数 https://en.wikipedia.org/wiki/Intrinsic_function.

尤其,BigInteger.multiplyToLen是 HotSpot 中的一个内在方法。有一个特殊的手工编码的汇编实现 http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/aa4ffb1f30c9/src/cpu/x86/vm/macroAssembler_x86.cpp#l7619在 JVM 源代码库中,但仅适用于 x86-64 架构。

您可以禁用此内在函数-XX:-UseMultiplyToLenIntrinsic强制 JVM 使用纯 Java 实现的选项。在这种情况下,性能将与复制代码的性能相似。

P.S.这里有一个list https://gist.github.com/apangin/7a9b7062a4bd0cd41fcc其他 HotSpot 内部方法。

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

运行JDK代码时Java JIT会作弊吗? 的相关文章

  • 使用比较器对对象进行排序给出空指针

    我正在尝试对包含 3 张卡的 ArrayList 进行排序 我正在用比较器来做这件事 这是否太过分了 Card getRank 返回 2 到 14 之间的整数 我完全不知道哪里出了问题 我之前已经成功完成了这个 并与我的其他代码进行了比较
  • Restlet 和 MULTIPART_FORM_DATA 或通过 Restlet 将文件放在 Google App Engine 上的其他方式

    我尝试通过 Restlet 接收文件 但只获得完整的 MULTIPART FORM DATA 如何提取我的特定文件 我找到了一些代码块 但它们的类型不可用 RESTlet 如何处理多部分 表单数据请求 https stackoverflow
  • eclipse juno 打开时出错

    在安装 Eclipse 并正常工作一年多后 我今天打开 Eclipse Juno 并在打开工作区时收到一条错误消息 我使用的是 Windows 8 64 位 Java 64 位和 Eclipse 64 位 此后我尝试重新安装 Java 和
  • 如何用Java创建图像

    比如说在我的程序中 我有这个paint 方法 我的愿望是创建所绘制的矩形的图像 使用 for 循环 我尝试了下面的方法 它确实给了我那些矩形 蓝色 但背景是全黑的 当我运行程序而不创建图像 仅在 JFrame 上绘制矩形时 背景为白色 我怎
  • java.lang.NoClassDefFoundError:HttpSessionListener

    我正在尝试部署一场我没有编写的战争 但我在日志中收到此错误 java lang NoClassDefFoundError HttpSessionListener 我知道 HttpSessionListener 位于servlet api j
  • 如何检查字符串是否具有特定模式[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 用户输入任意字符串 程序会区分该字符
  • RSA 加密-解密:BadPaddingException:数据必须以零开头

    对于一个被问了很多次的问题 我很抱歉向您询问您的技能 我有一个关于 RSA 加密的问题 我已经检查过有关此问题的其他主题 但没有找到任何有用的答案 我希望你能帮助我 我想读取一个文件 加密其内容 然后解密它并将这些解密的字节放入一个新文件中
  • Selenium - 保存网站,包括所有图像、css、dom

    我想使用 firefox 或 chrome 访问带有 selenium 的页面 当页面加载时 我想从页面下载所有图像 css dom 我想存储每张图像 就像我在其中找到它们一样 chrome gt Tools gt Development
  • Java 中的本机方法

    我花了一些时间学习什么是 Java Native 方法以及它们是在平台相关代码 主要是 C 中实现的 但是我在哪里可以找到这些 Java 的本机实现呢 例如 Thread 类的 sleep long millis 方法是本机的 但它的实现代
  • 文件保存在文件系统中 VS 保存在数据库中

    我正在设计一个 servlet 或 Struts2 中的操作 用于文件 图像 文档等 下载 但我想知道哪种更好的方法可以将文件保留在文件系统和数据库中 只需保留文件的路径或将文件保留在数据库中 如 BLOB 我知道当我查询数据库时 哪里的
  • Java - 同步方法导致程序大幅减慢

    我正在尝试了解线程和同步 我做了这个测试程序 public class Test static List
  • Java 泛型和数字类型

    我想创建一个通用方法来有效地执行此操作 class MyClass static
  • 如何减少 JSF 中的 javax.faces.ViewState

    减少 JSF 中视图状态隐藏字段大小的最佳方法是什么 我注意到我的视图状态约为 40k 这会在每次请求和响应时下降到客户端并返回到服务器 特别是到达服务器时 这对用户来说会显着减慢 我的环境 JSF 1 2 MyFaces Tomcat T
  • JSP 作为电子邮件模板

    有没有办法发送 MIME 电子邮件 其中电子邮件正文源自 JSP 我需要使用 Javamail 发送一封电子邮件 其中包含一个表格 我认为如果我可以使用 JSP 来完成所有格式设置和布局 将会很方便 在这个线程中 Java 电子邮件模板的建
  • 如何获取队列中的第 n 个项目?

    我的应用程序中有许多队列和优先级队列 我想轻松访问这些队列中的第 n 个项目 但没有看到使用 API 实现此目的的简单方法 我想我可以创建一个Iterator并迭代到第 n 个元素或使用toArray index 但似乎应该有一个更简单的方
  • 如何在Webview中保存用户名和密码

    目前 我还在学习Android开发的过程中 所以如果我的这个问题对你来说不太容易理解 请原谅 我创建了一个 Android 应用程序 它使用 RecyclerView 显示一组列表 当用户单击列表中的每个名称时 它会将它们重定向到一组不同的
  • Android - 保持用户登录状态

    我正在尝试使用 PHP 和 MySQLi for Android 进行登录 我不明白的是如何保持用户登录状态 我看到一个简单的教程 其中有人使用 SQLite 来保护信息 但我不知道这是否真的安全 如何保存用户信息以保持用户登录状态 谢谢
  • 有时 Properties.load() 会跳过行

    在以下情况下 Properties load 会跳过 InputStream 的第二行 这是 Java 的错误还是正常行为 public class PropTest public static void main String args
  • 如果所有类不在同一个包中,Spring @autowired 不起作用

    我有四个包裹 com spring org Files HomeController java com spring org dao Files SubscriberDao java SubscriberDaoImpl java com s
  • 根据 Java 环境变量中的值创建使用 @JsonIgnore 的自定义注释

    我需要创建一个新的注释 用于在环境变量设置时忽略输出 JSON 文件中的字段var false 我尝试使用JsonAnnotationIntrospector 但无法获得预期的输出 public class Vehicle String v

随机推荐