java 慢,Java真的慢吗?

现代Java是最快的语言之一,即使它仍然是一个内存猪。 Java有缓慢的声誉,因为它以前需要很长时间为VM启动。

如果你仍然认为Java很慢,请参见the benchmarks game结果。用先行编译语言(C,Fortran等)编写的严格优化的代码可以胜过它;然而,Java可以是PHP,Ruby,Python等的10倍多。有特定的领域,它可以击败常见的编译语言(如果他们使用标准库)。

现在没有借口为“慢”Java应用程序。开发人员和遗留代码/库是责怪的,远远超过语言。还有,责怪任何企业。

公平地说,“Java是慢”人群,这里是仍然缓慢的区域(2013年更新):

>库通常是为了“正确性”和可读性而不是性能。在我看来,这是Java仍然有不良的声誉,尤其是服务器端的主要原因。这使得String问题指数级更糟。一些简单的错误是常见的:对象通常用于代替原语,降低性能和增加内存使用。许多Java库(包括标准的)将经常创建字符串,而不是重用可变或更简单的格式(char []或StringBuffer)。这是缓慢的,并创建了大量的垃圾后来收集。为了解决这个问题,我建议开发人员尽可能使用原始集合,特别是Javalution的库。

>字符串操作有点慢。 Java使用不可变的,UTF-16编码的字符串对象。这意味着您需要更多的内存,更多的内存访问,并且一些操作比ASCII(C,C)更复杂。当时,这是对可移植性的正确决定,但它承载的性能成本很小。 UTF-8现在看起来更好的选择。

>数组访问比C慢一点,由于边界检查。惩罚过去是大的,但现在很小(Java 7优化了很多冗余边界检查)。

>缺乏任意内存访问可以使一些I / O和位级处理速度变慢(例如压缩/解压缩)。这是大多数高级语言的安全特性。

> Java使用比C多LOT内存,如果你的应用程序是内存绑定或内存带宽绑定(缓存等),这使它更慢。另一方面是分配/释放是快速的(高度优化)。这是现在大多数高级语言的一个特性,并且由于对象和使用GC而不是显式内存分配。加上坏图书馆的决定。

>基于流的I / O缓慢,由于(IMO,差的选择)要求在每个流访问上的同步。 NIO固定这个,但是使用起来很痛。可以通过读取/写入数组,而不是一次一个元素来解决这个问题。

> Java不提供同样的低级功能C,所以你不能使用脏内联汇编技巧,使一些操作更快。这提供了可移植性,并且是大多数高级语言的一个特性。

>通常将Java应用程序绑定到非常旧的JVM版本。特别是服务器端。与最新版本相比,这些旧的JVM可能难以置信的低效率。

最终,Java被设计为以牺牲一些性能为代价提供安全性和可移植性,并且对于一些真正要求苛刻的操作,它显示出来。它的大部分的缓慢的声誉不再是应得的。

但是,有几个地方的Java比大多数其他语言更快:

>内存分配和取消分配

是快速和便宜。我见过的情况

在那里它是20%更快(或更多!)到

分配一个新的,多kB的数组

重用缓存的一个。

>对象实例化和面向对象的特性使用起来很快(在某些情况下比C快),因为它们是从头开始设计的。这部分来自良好的GC,而不是显式分配(这对于许多小对象分配更友好)。一个可以编码C打败这(通过滚动定制内存管理和有效地执行malloc),但这不容易。

>方法调用基本上是免费的,在某些情况下比大方法代码更快。 HotSpot编译器使用执行信息来优化方法调用,并具有非常高效的内联。通过使用附加的执行信息,它有时可以胜过提前编译器,甚至(在极少情况下)手动内联。与C/C++比较,如果编译器决定不内联,方法调用具有小的性能损失。

>同步和多线程是容易和高效的。 Java被设计为从一开始就是线程感知的,它显示。现代计算机通常具有多个内核,并且由于线程是内置的语言,你可以很容易地利用。基本上,额外的100%到300%的速度提升与标准的单线程C代码。是的,仔细编写C线程和库可以击败这一点,但这是一个额外的工作,为程序员。

>字符串包括长度:一些操作更快。这个节拍使用空格分隔的字符串(在C中常见)。在Java 7中,Oracle取出了String.subString()优化,因为人们使用它愚蠢,并获得内存泄漏。

>数组副本是高度优化的。在最新版本中,Java对System.arraycopy使用手动调整的汇编器。结果是,在arraycopy / memcopy-heavy操作中,我已经看到我的代码在C中通过合理的边距击败等效。

> JIT编译器聪明地使用L1/L2缓存。时间前编译程序不能实时地将它们的代码调整到特定的CPU&系统。 JIT以这种方式提供了一些非常有效的循环变换。

一些其他的历史事实促成了“Java是缓慢”的声誉:

>在JIT编译之前(Java 1.2 / 1.3),语言只是解释,而不是编译,因此非常慢。

> JIT编译需要时间来变得高效(每个版本的主要改进)

>多年来,类加载已经变得更加高效。它在启动过程中效率很低,运行缓慢。

> Swing和UI代码没有使用本机图形硬件非常好。

>摇摆只是可怕。我责怪AWT和Swing为什么Java从来没有在桌面上。

>大量使用库类中的同步;非同步版本现在可用

> Applet永远加载,因为通过网络传输一个完整的JAR和加载VM启动。>同步用于承担严重的性能损失(这已经针对每个Java版本进行了优化)。反思仍然是昂贵的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值