Java真的很慢吗?
Java以速度慢而著称。
- Java真的很慢吗?
- 如果是,为什么?瓶颈在哪里(或曾经如此)?是因为JVM效率低下吗?垃圾回收?纯字节码库而不是JNI包装的C代码?许多其他语言具有这些功能,但它们没有这种缓慢的声誉。
Java以速度慢而著称。
现代Java是最快的语言之一,尽管它仍然是一个内存占用。Java以速度慢著称,因为过去需要很长时间才能启动VM。
如果您仍然认为Java很慢,请参阅基准测试游戏结果。用提前编译的语言(C,Fortran等)编写的严格优化的代码可以击败它;但是,Java的速度可以超过PHP,Ruby,Python等的10倍以上。在一些特定的领域,它可以击败常见的编译语言(如果它们使用标准库)。
现在没有借口“慢”Java应用程序。开发人员和遗留代码/库是罪魁祸首,远远超过语言。另外,责怪任何“企业”。
编写库通常是为了“正确性”和可读性,而不是性能。在我看来,这是Java仍然声誉不佳的主要原因,尤其是服务器端。这使得字符串问题呈指数级恶化。一些简单的错误很常见:对象通常用于代替基元,从而降低性能并增加内存使用量。许多Java库(包括标准库)会经常创建字符串,而不是重用可变或更简单的格式(char[]或StringBuffer)。这很慢,并且会产生大量垃圾以供以后收集。为了解决这个问题,我建议开发人员尽可能使用原始集合,尤其是Javalution的库。
字符串操作有点慢。Java 使用不可变的 UTF-16 编码字符串对象。这意味着您需要更多的内存,更多的内存访问,并且某些操作比ASCII(C,C++)更复杂。当时,这是可移植性的正确决定,但它的性能成本很小。UTF-8 现在看起来是一个更好的选择。
由于边界检查,与 C 相比,数组访问速度稍慢。惩罚过去很大,但现在很小(Java 7优化了许多冗余边界检查)。
缺少任意内存访问会使某些 I/O 和位级处理速度变慢(例如压缩/解压缩)。这是现在大多数高级语言的安全功能。
Java使用的内存比C多得多,如果您的应用程序受内存限制或内存带宽限制(缓存等),这将使它变慢。另一方面,分配/解除分配速度非常快(高度优化)。这是现在大多数高级语言的一个功能,并且由于对象和使用GC而不是显式内存分配。再加上糟糕的图书馆决策。
基于流的 I/O 速度很慢,因为(IMO,糟糕的选择)需要对每个流访问进行同步。NIO修复了这个问题,但使用起来很痛苦。可以通过对数组进行读/写来解决此问题,而不是一次对元素进行读/写。
Java没有提供与C相同的低级功能,因此您不能使用肮脏的内联汇编程序技巧来使某些操作更快。这提供了可移植性,并且是现在大多数高级语言的一个功能。
经常看到Java应用程序绑定到非常旧的JVM版本。尤其是服务器端。与最新版本相比,这些旧的JVM可能效率低下。
最后,Java被设计为以牺牲一些性能为代价来提供安全性和可移植性,对于一些真正苛刻的操作,它显示了这一点。它的大部分缓慢声誉不再值得。
内存分配和取消分配既快速又便宜。我见过这样的情况,分配一个新的、多kB的数组比重用缓存的数组快20%(或更多!)。
对象实例化和面向对象的功能使用起来非常快(在某些情况下比C++更快),因为它们从一开始就被设计进来了。这部分来自良好的GC而不是显式分配(这对许多小对象分配更友好)。人们可以编写C来击败这一点(通过滚动自定义内存管理和有效地执行malloc),但这并不容易。
方法调用基本上是免费的,在某些情况下比大方法代码更快。HotSpot 编译器使用执行信息来优化方法调用,并具有非常有效的内联。通过使用额外的执行信息,它有时可以优于提前编译器,甚至(在极少数情况下)手动内联。与 C/C++相比,如果编译器决定不内联,则方法调用会降低一点性能。
同步和多线程操作简单高效。Java从一开始就被设计为线程感知的,它证明了这一点。现代计算机通常具有多个内核,并且由于线程内置于语言中,因此您可以非常轻松地利用它。基本上,与标准的单线程C代码相比,速度提升了100%到300%。是的,精心编写的C线程和库可以解决这个问题,但这对程序员来说需要做很多额外的工作。
字符串包括长度:某些操作更快。这使用空分隔的字符串(在C中很常见)进行节拍。在Java 7中,Oracle取消了String.subString()优化,因为人们愚蠢地使用它并导致内存泄漏。
阵列拷贝经过高度优化。在最新版本中,Java使用手动调谐的汇编程序进行System.arraycopy。结果是,在数组复制/memcopy重度操作中,我看到我的代码以合理的边距击败了C中的等效代码。
JIT 编译器在使用 L1/L2 缓存方面很聪明。提前编译的程序无法根据运行它们的特定CPU和系统实时调整其代码。JIT 以这种方式提供了一些非常有效的循环转换。
最初,Java并不是特别快,但它也不是太慢。如今,Java非常快。从我交谈过的人那里,Java缓慢的印象来自两件事:
VM 启动时间慢。与本机应用程序相比,早期的Java实现需要很长时间才能启动和加载所需的库和应用程序。
界面缓慢。早期的摇摆很慢。大多数Windows用户发现默认的Metal L&F丑陋,这可能也无济于事。
鉴于上述几点,难怪人们会得到“Java很慢”的印象。
对于习惯于开发本机应用程序甚至 Visual Basic 应用程序的用户或开发人员来说,这两点是应用程序中最明显的东西,它是您对应用程序的第一印象(除非它是非 GUI 应用程序,在这种情况下,只有 1. 适用)。
当应用程序需要 8 秒才能启动时,您不会说服用户“它执行代码非常快”,而他的旧 Visual Basic 应用程序会立即启动 - 即使代码执行和启动时间可能根本没有连接。
破坏第一印象是开始谣言和神话的好方法。谣言和神话很难扼杀。
简而言之,Java并不慢。“Java是慢态度”的人是基于10多年前对Java的第一印象。