您现在的位置是:亿华云 > 域名
Java比C++慢?看了测试结果,颠覆了我的认知,不得不说JIT真的强
亿华云2025-10-04 03:29:07【域名】0人已围观
简介本文转载自微信公众号「Java大厂面试官」,作者laker。转载本文请联系Java大厂面试官公众号。每一个优秀的人,都有一段沉默的时光。那一段时光是付出了努力,忍受了孤独和寂寞,日后说起时,自己都被感
本文转载自微信公众号「Java大厂面试官」,测试作者laker。结果转载本文请联系Java大厂面试官公众号。颠覆
每一个优秀的测试人,都有一段沉默的结果时光。那一段时光是颠覆付出了努力,忍受了孤独和寂寞,测试日后说起时,结果自己都被感动的颠覆日子。
1. 概述
编程语言根据其抽象级别进行分类。测试我们区分高级语言(Java,结果Python,颠覆JavaScript,测试C ++,结果Go),颠覆低级语言(汇编程序),最后是机器代码。
每个高级语言代码(例如Java)都需要转换为机器本地代码才能执行。该翻译过程可以是编译或解释。但是,还有第三种选择。试图利用两种方法的组合。
2. 编译与解释
让我们开始研究编译和解释语言之间的一些差异。
2.1 编译语言
编译器将编译语言(C ++,Go)直接转换为机器码。亿华云
在执行之前,它们需要明确的构建步骤。这就是为什么每次更改代码时都需要重新编译程序。
编译语言往往比解释语言更快,更有效。但是,它们生成的机器码是特定于平台的。
2.2 解释语言
在解释语言(Python,JavaScript)中,没有构建步骤。相反,解释器在执行程序时对程序的源代码进行操作。
曾经认为解释语言比编译语言要慢得多。但是,随着即时编译(JIT)的发展,性能差距正在缩小。JIT编译器在程序运行时将代码从解释语言转换为机器码。
此外,我们可以在Windows,Linux或Mac等多个平台上执行解释后的语言代码。解释代码与特定类型的CPU体系结构没有关联。
3. Write Once Run Anywhere
Java和JVM在设计时考虑了可移植性。服务器租用因此,当今大多数流行的平台都可以运行Java代码。
这听起来似乎暗示着Java是一种纯解释性语言。但是,在执行之前,需要将Java源代码编译为字节码。字节码是JVM固有的一种特殊机器语言。JVM在运行时解释并执行此代码。
它是JVM为支持Java的每个平台构建和定制的,并不是我们的程序或库。
JVM也具有JIT编译器。这意味着JVM在运行时优化我们的代码,以获得与编译语言相似的性能优势。
4. Java编译器
javac的命令行工具把Java源代码编译转换成Java类文件(xxx.class)与平台无关的字节码:
$ javac HelloWorld.java源代码文件带有.java后缀,而包含字节码的类文件则带有.class后缀。
5. Java虚拟机
编译的类文件(字节码),可以由JVM执行:
$ java HelloWorld Hello Java!在运行时如何将字节码转换为机器本机代码。高防服务器
5.1 架构概述
JVM由五部分组成:
类加载器 JVM内存结构 执行引擎 本地方法接口 本地方法库5.2 类加载器
JVM利用ClassLoader将已编译的类文件加载到JVM内存
除加载外,ClassLoader还执行链接和初始化。
验证字节码是否存在安全漏洞 为静态变量分配内存 用原始引用替换符号内存引用 将原始值分配给静态变量 执行所有静态代码块5.3 执行引擎
执行引擎负责读取字节码,将其转换为机器本机代码并执行。
三个主要组件负责执行,包括解释器和编译器:
由于JVM与平台无关,因此它使用解释器执行字节码 JIT编译器在重复的方法调用处,把字节码编译为本地代码以提高性能。 垃圾收集器收集并删除所有未引用的对象。执行引擎利用本机方法接口(JNI)来调用本地库和应用程序。
5.4 即时编译器(JIT)
解释器的主要缺点是:每次调用方法时,都需要解释执行,这比编译的本机代码要慢。Java使用JIT编译器来克服此问题。
JIT编译器不能完全替代解释器。执行引擎仍在使用它。但是,JVM根据调用方法的频率使用JIT编译器。
JIT编译器将整个方法的字节码编译为机器本机代码,因此可以直接重用。与标准编译器一样,生成中间代码,进行优化,然后生成机器本机代码。
探查器是JIT编译器的特殊组件,负责查找热点。JVM根据运行时收集的性能分析信息来决定要编译的代码。
这样的效果是,经过几个执行周期,Java程序可以更快地执行其工作。JVM了解到热点后,便可以创建本机代码,从而使运行速度更快。
6. 性能比较
让我们看一下JIT编译如何提高Java的运行时性能。
6.1 斐波那契数列性能测试
我们将使用一种简单的递归方法来计算第n个斐波那契数:
private static int fibonacci(int index) { if (index <= 1) { return index; } return fibonacci(index-1) + fibonacci(index-2); }为了衡量重复方法调用的性能收益,我们将运行Fibonacci方法100次:
for (int i = 0; i < 100; i++) { long startTime = System.nanoTime(); int result = fibonacci(12); long totalTime = System.nanoTime() - startTime; System.out.println(totalTime); }首先,我们将正常编译并执行Java代码:
$ java Fibonacci.java然后,我们将在禁用JIT编译器的情况下执行相同的代码:
$ java -Djava.compiler=NONE Fibonacci.java最后,我们将在C ++和JavaScript中实现并运行相同的算法进行比较。
6.2 性能测试结果
让我们看一下运行斐波那契数列测试后以纳秒为单位测量的平均性能:
使用JIT编译器的Java – 2726 ns –最快 没有JIT编译器的Java – 17965 ns –慢559% 没有O2优化的C ++ – 9435 ns –降低246% 具有O2优化的C ++ – 3639 ns –慢33% JavaScript – 22998 ns –慢743%在此示例中,使用JIT编译器,Java的性能提高了500%以上。但是,JIT编译器确实需要运行一些才能运行。
有趣的是,即使在启用O2优化标志的情况下编译C ++,Java的性能也比C ++代码好33%。当仍在解释Java时,C ++在前几次运行中的性能要好得多。
Java还胜过与Node一起运行的等效JavaScript代码,后者也使用JIT编译器。结果显示性能提高了700%以上。主要原因是Java的JIT编译器启动速度更快。
7. 思考
从技术上讲,可以将任何静态编程语言代码直接编译为机器代码。也可以逐步解释任何编程代码。
与许多其他现代编程语言类似,Java使用编译器和解释器的组合。目标是利用两全其美,实现高性能和平台无关的执行。
在本文中,我们重点介绍了HotSpot中的工作方式。HotSpot是Oracle默认的开源JVM实现。Graal VM也基于HotSpot,因此适用相同的原理。
如今,最流行的JVM实现使用解释器和JIT编译器的组合。但是,其中一些也可能使用其他方式。
8. 结论
Java使用了两种方法的组合。
我们用Java编写的源代码在构建过程中首先被编译为字节码。然后,JVM解释生成的字节码以供执行。但是,JVM还在运行时使用JIT编译器来提高性能。
翻译于:
https://www.baeldung.com/java-compiled-interpreted
很赞哦!(8817)
相关文章
- 二、如何选择合适的域名
- 可前进可后退,IDEA 中这个功能神了!
- TB级mysql数据之xtrabackup压缩备份迁移方案
- 用于 TypeScript 枚举的实用辅助函数
- 2、根据用户基础选择访问提供程序。由于互联问题的存在,接入商的选择也非常重要,如果用户群主要在联通,尽量选择联通接入较好的接入商,如果用户群主要在电信,那么选择电信接入较好的接入商。如果用户组位于国家/地区,则选择更好的访问提供程序进行交互。
- 开源第一弹:什么是HBASE?
- 彻底搞懂 npm、yarn 与 pnpm 依赖管理逻辑
- 面试突击:说一下线程池七个参数的含义?
- 一下域名,看有没有显示出你所解析的IP,如果有,就说明解析是生效的;如果没有,就说明解析是不生效的。
- Spark1.0.0部署指南