为什么Java表现比其他解释型语言更好?

8

为什么Java的性能要比像Python这样的其他解释型语言好得多?我知道这可能与它预先编译有关,但并发性呢?

JVM如何处理并发程序,而解释型语言不得不处理全局解释器锁等会大大降低性能的问题?


在现代全功能平台上,运行时会将代码编译为本地代码。解释器仅在最初用于收集统计信息,以便对生成的本地代码进行优化。 - Affe
3
Java并非像Python一样完全解释执行,而是编译为中间语言Java字节码(Java Bytecode),这种方式更快速地进行解释。 - le3th4x0rbot
非常感谢迄今为止提供的出色答案。我有点紧张,因为这是我第一次发布问题。 - Tarighat
@BaileyS Python 也被编译成字节码。 - sepp2k
@sepp2k,我不知道Python的这一点,但是这个观点仍然适用于与PHP、Perl等的比较... - le3th4x0rbot
2个回答

12
这是一个非常有趣的问题,但我不确定是否有简单的方法来回答它。现在的JVM使用一系列高度激进的优化来尝试提高性能。以下是其中几个:
这是一个非常有趣的问题,但我不确定是否有简单的方法来回答它。现在的JVM使用一系列高度激进的优化来尝试提高性能。以下是其中几个:
  • 动态编译:大多数优秀的JVM可以直接将字节码动态编译成机器码,然后以本地速度执行。
  • 多态行内缓存:许多JVM使用行内缓存来尝试改善方法分派的性能,通过记住过去调用了哪些函数。
  • 静态类型:由于Java是静态类型语言,字节码指令很少需要对对象类型进行昂贵的内省,以确定如何在其上执行操作。字段偏移量可以静态计算,虚拟函数表中的方法索引也可以预先计算。与像JavaScript这样没有静态类型的语言相比,解释起来更为困难。
  • 垃圾回收:JVM垃圾回收器经过优化,可以高效地分配和释放对象。它使用标记-清除和停止-复制技术的组合,使大多数分配变得非常快,并且易于快速回收大量内存。
  • 已知瓶颈点:一些JVM实现不会有一个巨大的VM锁,而是会自动插入额外的代码到每个编译/解释代码中,以定期与VM进行检查并确定它们是否可以继续运行。这样,如果JVM只需要在几个线程中进行垃圾回收,它可以在其他线程运行时进行。如果它需要进行停止-全球操作,它将仅在线程达到特定点时发生,这意味着简单的操作不必不断地检查VM状态。

还有许多我可能不知道的优化措施,但我希望这能帮助你找到答案!


1
值得注意的是,Java并非直接解释执行,而是预先编译为伪汇编指令,在运行时比完整的编程语言文本更快处理。 - le3th4x0rbot
还有JIT,这也是一个重要因素。 - fge
@fge- 这是一个很好的观点。我将其列为“动态编译”,而不是JIT。 - templatetypedef
是的,但 JIT 的大部分工作是将字节码序列转换为其他字节码序列... 如果我没记错,编译成机器代码还是相当新的,不是吗? - fge
@fge:只有当您认为“1999年”或“Java 1.2”是相当新的时候--http://en.wikipedia.org/wiki/HotSpot - Steven Schlansker

3

在编译过程中,Java代码几乎没有进行优化。

运行时JIT完成大部分编译工作。

Java相对而言功能较少,副作用也很小。这使得代码更容易被优化。

相比之下,解释型语言必须处理全局解释器锁等问题,这真的会拖慢程序速度吗?

这是一个实现问题。Java从一开始就设计了多线程支持。我猜Python是为脚本和快速开发周期而设计的,因此在这方面表现更佳。


你关于最后一点是完全正确的。 - Tarighat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接