为什么字节码可能比本机代码运行得更快

问题描述

||                                                                                                                       

解决方法

在关于编程的策划书中,James Gosling解释了:   詹姆斯:没错。这些天我们   击败真正优秀的C和C ++   编译器几乎总是如此。当你   转到动态编译器,您将获得   编译器的两个优势   在最后一刻运行。一   你知道什么芯片组吗   你在继续。这么多次   人们正在编译一块C   代码,他们必须对其进行编译才能运行   在普通的x86上   建筑。几乎没有   你得到的二进制文件特别好   为它们中的任何一个而调优。您下载   Mozilla的最新副本,它将   几乎可以在任何英特尔上运行   体系结构CPU。有很多   一个Linux二进制文件。非常通用   它是由GCC编译的   不是一个很好的C编译器。      当HotSpot运行时,它确切知道   您正在使用哪种芯片组。它   确切知道缓存的工作方式。它   确切知道内存层次结构   作品。它确切地知道所有   管道互锁在CPU中工作。   它知道什么指令集   该芯片具有的扩展。它   针对什么机器进行优化   轮到你了。然后另一半   是它实际上看到了   运行中的应用程序。可以   有统计数据知道哪个   事情很重要。它能够   内联C编译器可以执行的操作   永远不会做。得到的东西   内联在Java世界中很漂亮   惊人。然后你坚持   存储管理的工作方式   现代垃圾收集器。用   现代垃圾收集器,存储   分配非常快。     ,快速的JVM使用即时(JIT)编译。字节码在运行时即时转换为本地代码。 JIT提供了许多优化机会。有关JIT的更多信息,请参见此Wikipedia文章。     ,JVM有很多特色! 最快的将根据收集的性能特征将字节码动态编译为本地代码。所有这些都需要额外的内存,因此它们以内存为代价来购买速度。此外,达到最高速度还需要一段时间,因此对于寿命短的程序不会显示出任何好处。 即使这样,JamVM解释器(与Oracle JVM相比也很小)仍然可以达到已编译JVM的相当一部分的最高速度。 关于垃圾收集,速度再次来自于有足够的可用内存。真正的好处还在于从代码中消除了跟踪对象何时不再使用的责任。这样可以简化程序,减少出错的可能性。     ,好吧,这是一个古老的论点。几乎所有的东西都像Emacs和VI一样流行(但绝对不那么古老)。我已经看到很多C ++开发人员提供了很多关于为什么大多数性能基准测试(尤其是提到Java与C ++ __一样快)的说法,并且老实说他们有观点。 我没有足够的知识或时间去深入了解Java如何与C ++一样快,但是以下是其可能的原因... 1-当您要求两个非常有能力的开发人员用Java和C ++编写代码来解决一个现实世界中的问题(相同的问题)时,如果Java的执行速度比C ++快,我会感到惊讶。 C ++编写得很好时会占用Java会使用的部分内存。 (Java对象稍微有些膨胀)。 2- Java本质上是一种较简单的语言,其编写目的是确保难以编写次优代码。通过抽象化内存管理以及处理低级优化,它比Java更容易用Java编写良好的代码。 (我认为这是最重要的事情。。。用Java编写不好的代码很难。)另一方面,一个好的C ++开发人员比Java中的自动GC可以更好地处理内存管理。 (Java将所有内容存储在堆中,因此会使用更多内存...) 3- Java编译器已得到持续改进,热点等想法已证明比市场营销术语更好。 (当引入JIT时,这只是一个营销术语。据我说:。) 4-人机工程学或根据基础操作系统参数定制设置,使Java处理更好。因此,在某些环境中,要想像Java一样好表现并不难。 5-为Java开发人员开放高级并发和并行化api也是一个原因。 Java并发包可以说是编写可以利用当今多处理器环境的高性能代码的最简单方法。 6-随着硬件的价格越来越便宜,开发人员的能力已成为一个更大的因素,这就是为什么我认为,许多野生的c ++代码可能比Java慢。     ,Java Byte代码比大多数本机操作码更容易优化。由于字节码受到限制,并且您无法做一些危险的事情,因此可以更充分地进行优化。以指针别名为例。 http://en.wikipedia.org/wiki/Pointer_aliasing 在C / C ++中,您可以执行
char[] somebuffer = getABuffer();
char* ptr = &someBuffer[2];
memcpy(ptr,somebuffer,length);
在某些情况下,这很难优化,因为您无法确定是指什么。在Java中,这种事情是不允许的。 通常,您可以在更高的抽象级别上执行的代码变异比目标代码具有更强大的功能。