首先,我应该提到,我知道性能优化可能非常特定于项目这一事实。我现在基本上没有面对这些特殊的问题。我面临着JVM本身的一系列性能问题。
我现在想知道:
Java自动化了很多,在字节码级别和其他方面做了很多优化.然而,我认为其中的大部分必须由开发人员规划才能工作。
那么,如何用Java加速程序呢?:)
发布于 2010-07-12 18:08:54
我经常看到这个。顺序一般如下:
这种情况在每种语言中都会发生,但在Java、C#和C++中,抽象已经到了极致。因此,一定要注意最佳实践,同时也要了解什么是简单的软件。通常,它包括将这些最佳实践保存到真正需要它们的环境中。
发布于 2010-07-12 07:06:49
从编译器的角度来看,哪种代码优化是有意义的:例如,为了支持垃圾收集器,我将变量声明为final --非常遵循Eclipse中PMD的建议。
假设您正在讨论的是您可以对代码进行的潜在的微优化,答案几乎是零。提高应用程序性能的最佳方法是运行一个分析器来确定性能瓶颈在哪里,然后找出是否有什么可以加快它们的速度。
在大多数情况下,所有典型的技巧,比如声明类、变量和方法,最终,重新组织循环,改变原始类型,都是浪费精力的。JIT编译器通常比您做得更好。例如,最近的JIT编译器将分析所有加载的类,找出哪些方法调用不受重载的影响,而不将这些类或方法声明为final
。然后,它将使用更快的调用序列,甚至内联方法主体。
事实上,Sun专家说,一些程序员试图优化失败,因为他们实际上使JIT编译器更难应用它所知道的优化。
另一方面,更高级的算法优化绝对是值得的.如果您的分析器告诉您,您的应用程序正在花费大量的时间在该领域的代码。
在不寻常的情况下,使用数组而不是集合可能是值得的优化,在罕见的情况下,使用对象池也可能是值得的。但是,这些优化( 1)会使您的代码更复杂,更容易出错;2)如果使用不当,应用程序可能会慢下来。这类优化只能作为最后的手段来尝试。例如,如果您的分析表明这类HashMap<Integer,Integer>
是CPU瓶颈或内存占优势,那么最好是查找现有的专用Map
或Map
-like库类,而不是使用数组自己实现映射。换句话说,在高层次上进行优化。
如果您花费的时间足够长,或者您的应用程序足够小,那么仔细的微观优化可能会给您一个比依赖JIT编译器更快的应用程序(在给定的JVM版本/硬件平台上)。如果您正在实现一个小型应用程序,以便在Java中进行大规模的数字处理,那么微优化的回报很可能相当可观。但这显然不是一个典型的案例!对于典型的Java应用程序,工作量足够大,性能差异也很小,因此不值得进行微优化。
(顺便说一句,我不认为声明变量会对GC性能产生任何可能的影响。GC必须在每次遇到变量时跟踪它,不管它是否是最终变量。此外,在某些情况下,最终变量实际上可以更改,这是一个公开的秘密,因此GC假设它们不改变是不安全的,因为“创建一个悬空指针导致JVM崩溃”。)
发布于 2010-07-12 18:01:30
从编译器的角度来看,哪种代码优化是有意义的?
编译器无法推理的所有内容,因为编译器非常愚蠢,Java没有“按约定设计”(因此,这不能帮助哑巴编译器对代码进行解释)。
例如,如果您正在处理数据并使用int[]或long[]数组,您可能知道一些关于您的数据的信息,这是编译器无法理解的不可能的,您也可以使用低级别的位打包/压缩来提高代码中引用的局部性。
在那里,做了那件事,看到了巨大的加速。“超级智能编译器”到此为止。
这只是一个例子。有很多这样的案例。
记住,编译器是非常愚蠢的:它不能知道if ( Math.abs(42) >0)总是返回true。
这应该会给那些认为这些编译器“聪明”的人提供一些启发(如果Java有DbC,情况就会不同,但它没有)。
有哪些最佳实践: vmargs、堆和其他传递给JVM进行初始化的东西。我怎么才能在这里得到正确的值?有公式吗?还是尝试错误?
真正的答案是:不应该有。可悲的是,由于Java方面的严重失败,这种情况是如此可悲,以至于需要如此低级别的黑客。哦,还有一个“微小”的细节:玩VM微调只适用于服务器端应用程序。它不适用于桌面应用程序。
任何曾经在数百台或数千台机器上安装过Java桌面应用程序的人,在各种OSes上都非常清楚问题所在:完全的GC暂停会使您的应用程序看起来像坏了一样。OSX10.4上的Apple之所以能想到,是因为它的功能非常强大,但是所有的-- JVMs -都会受到这个问题的影响。
更糟糕的是:当您的应用程序要在成百上千个不同的配置上运行时,不可能在不同的OSes /VM/内存配置中“微调”GC的参数。
有人质疑这一点:请告诉我,你如何“微调”你的应用程序,知道它将在装有20 GB内存的八核Mac上运行(我有这样的设备的用户)和老的OS 10.4 PowerBook,其中有768 MB的内存。请?
但这并不坏:首先,你不应该关注超低级的细节,比如GC的“微调”。暗示这一点的事实证明了Java在其中有一个主要问题。
Java迷们会继续说“GC非常快,对象创建很便宜”,而这显然是错误的。TIntIntHashMap绕着HashMap。
还有一个原因,为什么在每一个新的JVM发行版中,您都会收到无数的发行说明,解释为什么-XXGCHyperSteroidMultiTopNotch提供的性能要好于每个酷酷的Java程序员必须知道的最后一个“大JVM param”:也许JVM毕竟在GC方面并没有那么出色。
因此,要回答您的问题:如何加快Java程序的速度?很简单,就像那些有价值的人所做的那样:停止不必要地创建大量的对象,停止不必要的自动(Un)装箱原语,因为它们的会杀死应用程序的功能。
TIntIntHashMap 拥有默认的HashMap是有原因的:出于同样的原因,我的应用程序现在比以前快得多。
我不再相信像“创建对象不需要任何代价”和“GC是超级优化的,不要担心它”之类的废话。
我正在使用Java来处理数据(我知道,我有点疯狂),使我的应用程序更快的一件事是停止相信围绕“廉价对象创建”和“惊人的快速GC”的所有宣传。
事实是:不是试图微调GC设置,而是停止创建大量垃圾,首先是。这可以这样说:如果改变GC设置从根本上改变了应用程序的运行方式,那么可能是时候怀疑您创建的所有不必要的垃圾对象是否真的需要了。
哦,你知道吗,我打赌我们会看到越来越多的发行说明,解释为什么Java版本x.y.z的GC比x.y.z的GC更快)
https://stackoverflow.com/questions/3226149
复制相似问题