关于 C/C++ 优化是在编译时产生的,而 Java 优化是在运行时产生的。是否有可能让 Java 程序比 C 中的相同程序(优化)更快?
我知道运行时优化可能比编译时间更好。因此,我想知道这些优化的收益是否可以与运行 JVM 的开销相比较。
关于 C/C++ 优化是在编译时产生的,而 Java 优化是在运行时产生的。是否有可能让 Java 程序比 C 中的相同程序(优化)更快?
我知道运行时优化可能比编译时间更好。因此,我想知道这些优化的收益是否可以与运行 JVM 的开销相比较。
理论上,是的。在实践中,这是极不可能的。
基本假设之一是 C/C++ 为二进制操作码目标编译一次,而 Java 为运行它的特定机器编译。这应该给 Java 带来优势。但现实情况是,即使 C/C++ 也可以有多个优化路径,在运行时动态选择,并获得特定目标编译的大部分好处。
相反,如 Rekin 所述,Java JVM 需要动态分析 Java 程序以了解要优化什么以及如何优化。分析本身就是一项昂贵的操作,并且无法从 Java JVM 中消除这种开销。另一方面,为当前工作负载选择正确的优化集可以带来优势。在实践中,大多数 C 程序(但不是全部:) 都针对它们的任务进行了很好的调整,并且几乎没有什么可以使用分析技术进行优化。
Java 中还有其他一些效果使这些编译问题完全相形见绌。可能在第一个位置是垃圾收集器。
垃圾收集器的首要任务是简化编程、处理和避免 C/C++ 中最讨厌的经常性错误之一,即内存泄漏。仅此特性就证明了在许多工业环境中大量使用 Java 是合理的。
然而,这是有代价的。一个非常大的。根据研究,有必要提供大约 5 倍的严格必要内存量,以确保垃圾收集器以最小的开销工作。因此,每当缺少这样的内存量时,GC 开销就会开始变得很大,从而使性能陷入困境。
不利的是,在某些情况下,释放内存分配费用的算法可能会允许更改算法,并采用更好、更快的算法。在这种情况下,Java 可以占据优势,并且比 C 程序更快。
但你可以猜到,这并不常见......
C/C++程序是专门为特定平台编写的,直接编译成机器码,必然更贴近自己运行的软硬件平台。因此他们会更快。
Java 优化内置在 JVM 中,并且通过及时 (JTI) 处理字节码的方式实现了最佳优化(就程序的执行速度而言)。尽管 JTI 被证明是内存密集型的。
因此,比较这些策略清楚地表明 C/C++ 原生代码会更快;因为即使使用 JTI,JVM 仍有一些开销将字节码转换为本机。
但这是为依赖平台和 java 更便携所付出的代价。
取自java 什么时候比 c++ 快(或者 JIT 什么时候比预编译快)?,我发现了一些场景的 Java 执行可以胜过 C/C++
很多小内存分配/释放。主要的 JVM 都有非常高效的内存子系统,垃圾收集比要求显式释放更有效(如果它真的想的话,它可以移动内存地址等)。
通过方法调用的深层层次结构进行有效访问。JVM 非常擅长删除任何不必要的东西,根据我的经验,通常比大多数 C++ 编译器(包括 gcc 和 icc)要好。这部分是因为它可以在运行时进行动态分析(即它可以过度优化并且只有在检测到问题时才去优化)。
将功能封装到小的短期对象中。
JVM 的开销是巨大的。它必须加载几个类,这些类位于 zip (jar) 文件中并且需要被提取。
对于每一个加载的类,都会对其运行一些静态分析方法,看看是否有代码不可达、操作数栈类型问题等。
然后,分析器会一直运行以决定哪些代码部分值得优化,这通常意味着这些方法需要调用数千次才能进行优化。
除此之外,您还可以获得垃圾收集器。
我真的无法想象一个正确编写的 C 程序,为它运行的平台编译,被 Java 等价物所超越。也许只有当您遇到一些罕见的极端情况时,JVM 进行了一些优化,而 C 编译器没有实现特定的优化。
当资源有限且上市时间更重要时,我看到 Java 比 C 运行得更快。在这种情况下,您没有时间像在 C 和 C++ 中那样高效地编写代码,您最终可能会做的事情效率低于 JVM 为您做的事情。即,如果您需要 JVM 已经做的事情,它可以更快。
如果您有一台拥有足够资源的机器,则开发人员的时间会更加昂贵/关键,您可以在更短的时间内获得一个工作稳定的系统,并有时间进行分析/优化,而 C 团队可能仍在修复所有核心转储. 您的里程会有所不同。
对于资源有限的设备,C 仍然占主导地位,因为您可以控制资源分配。顺便说一句,现在大多数手机都可以正常运行 Java(或 Objective-C)。