Ste*_*ini 180 java performance
Bob*_*Gee 236
现代Java是最快的语言之一,尽管它仍然是一种记忆力.Java的有用于速度缓慢,因为它曾经花费很长的时间VM启动的声誉.
如果您仍然认为Java很慢,请参阅基准测试游戏结果.用提前编译语言(C,Fortran等)编写的紧密优化代码可以击败它; 但是,Java的速度可以是PHP,Ruby,Python等的10倍.在特定领域,它可以胜过常见的编译语言(如果它们使用标准库).
现在没有"慢"Java应用程序的借口.开发人员和遗留代码/库应该归咎于远远超过语言.还有,责怪任何"企业".
库通常是为"正确性"和可读性而非性能而编写的.在我看来,这是Java仍然声名狼借的主要原因,尤其是服务器端.这使得String问题呈指数级恶化.一些简单的错误很常见:通常使用对象代替基元,从而降低性能并增加内存使用.许多Java库(包括标准库)将经常创建字符串,而不是重用可变或更简单的格式(char []或StringBuffer).这很慢并且会产生大量的垃圾以便以后收集.为了解决这个问题,我建议开发人员尽可能使用原始集合,尤其是Javalution的库.
字符串操作有点慢.Java使用不可变的,UTF-16编码的字符串对象.这意味着您需要更多内存,更多内存访问,而某些操作比使用ASCII(C,C++)更复杂.当时,这是可移植性的正确决定,但它的性能成本很低.UTF-8现在看起来是更好的选择.
由于边界检查,与C相比,数组访问速度稍慢.过去的惩罚很大,但现在很小(Java 7优化了很多冗余边界检查).
缺乏任意内存访问可能会使某些I/O和位级处理变慢(例如压缩/解压缩).这是现在大多数高级语言的安全功能.
Java使用的内存比C多,如果您的应用程序受内存限制或内存带宽限制(缓存等),则会使速度变慢.另一方面,分配/解除分配的速度非常快(高度优化).这是现在大多数高级语言的一个特性,并且由于对象和GC的使用而不是显式内存分配. 加上坏的图书馆决定.
由于(IMO,选择不当)要求在每个流访问上进行同步,基于流的I/O很慢.NIO解决了这个问题,但使用它很痛苦.通过对数组进行读/写操作,而不是一次一个元素,可以解决这个问题.
Java没有提供与C相同的低级功能,因此您不能使用脏内联汇编程序技巧来加快某些操作.这提供了可移植性,现在是大多数高级语言的一个特性.
通常看到Java应用程序与非常旧的JVM版本相关联.特别是服务器端.与最新版本相比,这些旧JVM的效率极低.
最后,Java旨在以牺牲一些性能为代价来提供安全性和可移植性,以及它所展示的一些非常苛刻的操作.它的缓慢声誉大部分都不再值得.
内存分配和解除分配快速且便宜.我已经看到分配一个新的多KB阵列比重用缓存的数据快20%(或更多!)的情况.
对象实例化和面向对象的特性使用起来非常快(在某些情况下比C++更快),因为它们从一开始就被设计出来.这部分来自良好的GC而不是显式分配(对许多小对象分配更友好).人们可以编写C代码(通过滚动自定义内存管理并高效地执行malloc),但这并不容易.
方法调用基本上是免费的,在某些情况下比大方法代码更快.该热点编译器使用的执行信息来优化方法调用,具有非常高效的内联.通过使用额外的执行信息,它有时可以胜过提前编译器甚至(在极少数情况下)手动内联.与C/C++相比,如果编译器决定不内联,方法调用会带来很小的性能损失.
同步和多线程简单而有效.Java从一开始就被设计为线程感知,并且它表明了.现代计算机通常具有多个内核,并且由于线程内置于该语言中,因此您可以非常轻松地利用它.与标准的单线程C代码相比,基本上可以提供100%到300%的额外速度提升.是的,精心编写的C线程和库可以击败这个,但这对程序员来说是一项额外的工作.
字符串包括长度:某些操作更快.这使用空分隔字符串(在C中很常见).在Java 7中,Oracle取消了String.subString()优化,因为人们愚蠢地使用它并且导致内存泄漏.
阵列副本经过高度优化.在最新版本中,Java使用手动调整的汇编程序进行System.arraycopy.结果是在arraycopy/memcopy-heavy操作中,我看到我的代码在C中以合理的余量击败了等价物.
JIT编译器很聪明地使用L1/L2缓存.提前编译的程序无法实时地将其代码调整到它们运行的特定CPU和系统.JIT以这种方式提供了一些非常有效的循环转换.
nos*_*nos 49
最初Java并不是特别快,但它也不是太慢.这些天,Java非常快.从与人交谈过的人们对Java缓慢的印象来自两件事:
虚拟机启动时间较慢.与本机应用程序相比,早期的Java实现需要很长时间才能启动并加载require库和应用程序.
慢UI.早期的挥杆很慢.它可能没有帮助大多数Windows用户发现默认的金属L&F丑陋.
鉴于以上几点,难怪人们得到了"Java缓慢"的印象.
对于用于开发本机应用程序甚至Visual Basic应用程序的用户或开发人员来说,这两点是应用程序中最明显的一点,它是您对应用程序的第一印象(除非它是一个非GUI应用程序,其中情况只有1.适用.).
当应用程序需要8秒钟启动时,你不会说服用户"它执行代码的速度非常快"与他立即启动的旧Visual Basic应用程序 - 即使代码执行和启动时间可能根本没有连接.
破坏第一印象是开始谣言和神话的好方法.谣言和神话很难被杀死.
简而言之,Java并不慢.拥有"Java态度缓慢"的人是基于10多年前对Java的第一印象.
Sam*_*ami 40
在阅读了一篇充满评论的页面后,说Java并不慢,我只需回答一个不同的意见.
语言的缓慢很大程度上取决于你对"快速"的期望.如果你认为C#很快,Java肯定也很快.如果您的问题域与数据库或半实时处理相关,那么Java肯定也足够快.如果您乐意通过添加更多硬件来扩展应用程序,那么Java可能很快.如果你认为5-10级的常数因子加速并不值得,你可能会认为Java很快.
如果对大型数据集进行数值计算,或者绑定到CPU资源有限的执行环境,那么5-10级的恒定加速将是巨大的.即使0.5加速也可能意味着计算完成时减少500小时.在这些情况下,Java只是不允许你获得最后一码的性能,并且你可能认为Java很慢.
Jer*_*fin 33
你似乎在问两个相当不同的问题:
其中第一个或多或少是"绳索有多长"的问题.它归结为你对"慢"的定义.与纯解释器相比,Java速度极快.与(通常)编译为某种字节码的其他语言相比,然后动态编译为机器代码(例如C#或.NET上的任何其他内容),Java大致相当.与通常编译为纯机器代码的语言相比,并且(通常很大的)团队除了改进他们的优化器(例如C,C++,Fortran,Ada)之外什么也没有做任何事情时,Java在一些事情上做得很好,但整体而言往往至少有点慢.
其中很多主要与实现有关 - 基本上,它归结为用户在动态/ JIT编译器运行时等待的事实,所以除非你有一个程序运行了很长一段时间才开始,所以难以证明编译器花费大量时间进行困难的优化.因此,大多数Java(和C#等)编译器都没有花费太多精力进行真正困难的优化.在很多情况下,与实施优化相比,优化程度更低.许多优化问题都是NP完成的,因此随着问题被攻击的大小,它们所花费的时间会迅速增长.将时间保持在合理范围内的一种方法是一次仅将优化应用于单个函数.当只有开发人员等待编译器时,您可以花费更长的时间,并将相同的优化应用于程序的更大块.同样,一些优化的代码非常多(因此可能非常大).同样,由于用户正在等待该代码加载(并且JVM启动时间通常是整个时间中的一个重要因素),实现必须平衡在一个地方保存的时间与在另一个地方丢失的时间 - 并且给出了很少的代码从毛茸茸的优化中获益,保持JVM较小通常更有益.
第二个问题是,使用Java,您经常会获得或多或少的"一刀切"解决方案.例如,对于许多Java开发人员来说,Swing本质上是唯一可用的窗口库.在像C++这样的东西中,实际上有几十个窗口库,应用程序框架等,每个窗口都有自己的易用性和快速执行之间的妥协,一致的外观和原生的外观和感觉等等.唯一真正的关键点是一些(例如Qt)可能非常昂贵(至少对于商业用途而言).
第三,用C++编写的许多代码(以及C更加如此)只是更老,更成熟.很多时候,它包含了几十年前编写的一系列例程,当时花费额外的时间优化代码是正常的预期行为.这通常会在代码更小更快的情况下获得真正的好处.C++(或C)获得了代码小而快的功能,但它实际上是开发人员的产品和代码编写时间的约束.在某种程度上,这导致了一种自我实现的预言 - 当人们关心速度时,他们经常选择C++,因为它具有这种声誉.他们将额外的时间和精力投入到优化中,并编写了新一代的快速C++代码.
总而言之,Java的正常实现使得最大化优化最多成为问题.更糟糕的是,在Java 可见的地方,诸如窗口工具包和JVM启动时间之类的东西通常比语言本身的执行速度发挥更大的作用.在很多情况下,C和C++也因为简单地在优化中更加努力的产品而受到赞誉.
至于第二个问题,我认为这在很大程度上取决于工作中的人性问题.一些狂热者提出了相当夸张的关于Java快速致命的说法.有人试了一下,发现即使是一个微不足道的程序也需要几秒钟的时间才能开始,并且当它运行时感觉缓慢且笨拙.很少有人可能会费心去分析事情,因为很多事情都是JVM的启动时间,以及当他们第一次尝试时,没有编译代码的事实 - 一些代码正在被解释,还有一些是在他们等待时编译的.更糟糕的是,即使它运行得足够快,对于大多数用户来说,外观和感觉通常看起来也很笨拙,所以即使客观测量显示出快速的响应时间,它仍然看起来很笨拙.
将这些添加在一起会导致相当简单和自然的反应:Java是缓慢,丑陋和笨拙的.鉴于大肆宣传它真的很快,有一种倾向过度反应和结论认为它非常缓慢,而不是(更准确)"稍微慢一点,而且主要是在特定情况下." 对于使用该语言编写前几个程序的开发人员来说,这通常是最糟糕的.在大多数语言中执行"hello world"程序会立即出现,但在Java中,JVM启动时会有一个容易察觉的暂停.即使是在紧密循环上运行速度慢得多的纯解释器,对于像这样的代码来说仍然会更快出现,只是因为它可以加载并开始执行一点点.
Dan*_*yer 16
它是早期(20世纪90年代中后期)Java的过时信息.与之前的版本相比,Java的每个主要版本都引入了显着的加速.由于Oracle显然将JRockit与Sun的JVM for Java 7合并,这种趋势似乎将继续下去.
与许多其他流行的现代语言(Python,Ruby,PHP)相比,Java在大多数用途中实际上要快得多.它与C或C++不完全匹配,但对于许多任务而言,它足够接近.真正的性能问题应该是它最终使用多少内存.
Tho*_*nin 14
"长启动时间"的主要罪魁祸首是动态链接.Java应用程序由已编译的类组成.每个类按名称引用其他类(对于参数类型,方法调用...).JVM必须在启动时检查并匹配这些名称.它会逐步增加,只在任何给定时间执行它所需的部分,但这仍然是一些工作要做.
在C应用程序中,链接阶段发生在编译结束时.它很慢,特别是对于大型应用程序,但只有开发人员才能看到它.链接产生一个可执行文件,操作系统只需要"按原样"加载到RAM中.
在Java中,每次运行应用程序时都会发生链接.因此启动时间很长.
已经应用了各种优化,包括缓存技术,并且计算机变得更快(并且它们比应用程序"更大"更"快"),因此最近问题的重要性大大降低; 但旧的偏见仍然存在.
至于之后的性能,我自己的基于数组访问的紧凑计算基准(主要是散列函数和其他加密算法)通常表明优化的C代码比Java代码快3倍左右; 有时C只比Java快30%,有时C可以快4倍,具体取决于实现的算法.当"C"代码实际上是大整数算术的汇编时,我看到了一个10倍因子,因为处理器提供的64x64-> 128乘法操作码但Java无法使用,因为它的最长整数类型是64位long.这是一个边缘案例.在实际条件下,I/O和内存带宽考虑因素阻止C代码实际上比Java快三倍.
小智 14
Java肯定很慢,特别是对于量化工作.
我将R,Python和C/C++与优化的多线程ATLAS库结合使用.在每种语言中,我可以在大约4秒内将矩阵乘以3000乘3000矩阵.在Java中使用Colt和Parallel Colt,相同的操作需要185秒!尽管这些java库本质上是并行的,但令人惊讶.
总而言之,纯Java不适合定量工作.Jblas似乎是Java中最好的线性代数库,因为它使用ATLAS.
我的机器是带有3 GB RAM 的HP Core 2 Duo.我使用的是64位Ubuntu 10.04(Lucid Lynx).
Spi*_*ams 10
对于大多数人与它交互的经验 - Java 很慢.在一些小程序出现之前,我们都看到咖啡杯在我们的浏览器上旋转.启动JVM并下载applet二进制文件需要一段时间,这会以一种被注意到的方式影响用户体验.
缓慢的JVM启动和applet下载时间明显标有Java咖啡杯,这无助于人们将等待与Java联系在一起.当Flash需要很长时间加载时,Flash加载程序会指定"加载"消息的标记,因此人们不会将Flash技术归咎于整体.
所有这些都与Java在服务器上的性能无关,也与Java在浏览器外部使用的许多其他方式无关.但这是人们看到的内容,以及非Java开发人员在考虑Java时所记得的内容.
Java有被缓慢的,因为它的名声是缓慢的.Java的第一个版本没有或相当差的Just In Time编译.这意味着代码(尽管字节码)正在被解释,因此即使对于最简单的操作(如添加两个整数),机器也必须进行各种比较和指针解引用和函数调用.JIT编译器一直在不断改进; 现在,如果我不小心编写C++代码和粗略地编写Java代码,Java有时会胜过 C++,因为JIT编译器意识到我有一些不必要的指针解除引用并将为我处理它.
如果您想了解JIT编译的差异有多大,请查看计算机语言基准游戏中的解释与非解释基准.(Pidigits使用外部库进行所有计算,因此基准测试不会改变;其他计算机显示6-16倍的加速!)
所以,这是主要原因.还有其他一些不太重要的原因没有帮助:最初,Java启动时间很慢(现在已经修复); Java中的Web应用程序需要花费很长时间才能下载(现在宽带可以广泛使用,并且需要大量电影等); UI Swing不是(现在仍然没有)以性能为基础编写的,所以它比C++中的等价物要简单得多.
斯特凡诺:
我从一开始就使用Java,所以从我的观点来看,缓慢的名声是由非响应和慢的GUI前端(AWT,然后是Swing)和Applet创建的,可能是因为它的启动时间较慢. VM的.
Java在VM领域已经规定并推动了大量的研究,并且已经有了相当多的改进,包括垃圾收集(你可以实际调整很多东西;但是,我常常看到只使用默认值的系统)和热点优化(在开始时,可能仍然在服务器端更有效).
后端的Java和计算级别并不那么慢.柯尔特是最好的例子之一:
最新稳定的Colt版本打破了JDK ibm-1.4.1,RedHat 9.0,2x IntelXeon@2.8 GHz的1.9 Gflop/s障碍.
应该考虑主流Java之外的许多东西,比如Realtime Java或增强速度的特殊机制,如Javolution,以及Ahead-Of-Time编译(如gcj).此外,还有可以直接执行Java Bytecode的IC,例如当前iPhone和iPod ARM Jazelle中的那个.
我认为通常今天它是一个政治决定(就像iPhone/iPod上没有Java支持一样),并且决定将Java作为一种语言(因为许多人认为它太冗长).
但是,现在Java VM还有许多其他语言(例如Python,Ruby,JavaScript,Groovy,Scala等),它们可能是另一种选择.
我个人继续喜欢它作为一个灵活可靠的平台,具有出色的工具和库可用性,允许人们使用从最小的设备(例如JavaCard)到最大的服务器的所有东西.