可以走多快?


39

Go是少数应该“接近金属”运行的语言之一,也就是说,它是经过编译,静态类型化的,并且无需VM即可在本地执行代码。这应该使其相对于Java,C#等具有速度优势。但是,它似乎落后于Java(请参阅《编程语言实战》

我假设不太成熟的编译器对此负有很大责任,但是还有其他原因吗?Go的设计中是否有固有的功能可以阻止它比Java更快地运行?我对运行时模型有一个非常简单的看法,但是由于本地代码的执行,看来至少在原则上它应该比Java运行得更快。


3
给定足够智能的编译器(和/或VM和/或JIT编译器),给定的语言总是可以运行得更快(嗯,有物理上的限制,仅此而已)。只要不存在这种足够智能的编译器,这种无聊的做法当然不会帮助任何人。请注意,尽管Java已经具有足够智能的实现,而且它们非常智能。生活中的另一个事实是,代码运行对运行时性能的影响与实现至少相同。

1
我理解这一点,但是我想知道Go的速度匹配/超越是否合理(例如,随着Java的成熟)。
格雷格·斯洛德科维奇

17
编程语言没有速度。语言实现也​​没有。给定的语言实现对于某些给定的输入具有速度,并且该速度在很大程度上取决于输入。

8
叫醒我..,然后再走... WHAM!。对不起,我无法抗拒。标志了.. 标志了..
蒂姆·波斯特

2
@delnan-说“ Java”要比说“ Java(TM)SE运行时环境(版本1.6.0_25-b06)或Java HotSpot(TM)64位服务器VM(版本20.0-b11)要容易得多。 ,混合模式)“ :-)
igouy 2011年

Answers:


46

就语言设计而言,实际上没有什么可以使Go慢于Java的。实际上,它使您可以更好地控制数据结构的内存布局,因此对于许多常见任务而言,它应该更快一些。但是,当前的主要Go编译器,调度程序,垃圾收集器,regexp库和许多其他东西并未特别优化。这种情况正在稳步改善,但是重点似乎是要比获得微基准测试足够有用,简单和快速。

在链接的基准测试中,Go在二叉树和regexp测试上输给了Java。这些分别是内存管理系统和regexp库的测试。Go的内存管理可能会更快,并且随着时间的推移肯定会有所改善,而当前的标准regexp库是一个占位符,可用于即将实现的更好的实现。因此,输掉这两个不足为奇,并且在不久的将来利润率应该会更窄。

对于k核苷酸基准测试,很难比较,因为Java代码看起来正在使用不同的算法。即使编写了代码,Go代码也肯定会从编译器,调度程序和分配器的改进中受益,但是如果我们想更准确地进行比较,则有人必须重写Go代码才能做得更聪明。

Java在mandelbrot基准测试中胜出,因为它全部是浮点算术和循环,这是JVM在运行时生成非常好的机器代码和提升内容的好地方。相比之下,Go拥有一个非常简单的编译器,该编译器当前不提升,展开或生成非常严格的机器代码,因此它丢失并不奇怪。但是,请记住,Java计时不计算JVM的启动时间,也不计算JVM正常运行所需的运行时间。对于长时间运行的程序,这无关紧要,但是在某些情况下很重要。

至于其余的基准测试,Java和Go基本上是并驾齐驱的,其中Go占用更少的内存,并且在大多数情况下,更少的代码。因此,尽管在许多测试中Go的运行速度都比Java慢,但Java的运行速度却相当快,相比之下Go的运行情况还不错,而且Go可能会在不久的将来变得更快。

我期待gccgo(使用gcc代码生成的Go编译器)何时成熟。对于许多类型的代码,这应该使Go几乎与C保持一致,这将很有趣。


2
做得好,为了理解始终有必要查看源代码并检查正在执行的操作!
igouy 2011年

1
有关这些程序的Java启动时间,请参见 shootout.alioth.debian.org/help.php#java
igouy 2011年

2
正是我所希望的答案,谢谢!
Greg Slodkowicz 2011年

更少的代码和内存使用量,可以编译为机器代码,设计更好。所有这些都取代了速度劣势。
Moshe Revah,2011年

22
  1. 甚至没有说解决了什么问题,整个基准毫无意义。
  2. JVM和CLR都使用JIT生成机器代码。没有理由这应该变慢。它只是花费你很多年才能启动。
  3. Go旨在快速构建。您没有大量的编译时间和启动时间优化。在Java应用程序启动时,Go会编译自己的标准库。

可以在运行时更快吗?是。Go在运行时会更快吗?我不知道。也许编译器生成器会以编译时间为代价添加可选的优化。但是我认为他们对此没有太大兴趣。他们在Google工作。
他们想要的是一种允许快速开发并在其工作中表现出色的语言。天哪,即使该基准是可信的,这也意味着它们的速度是C的一半,是Python的14倍。这绰绰有余。
硬件便宜,代码昂贵。随着投资的增加,代码往往变得越来越大,速度越来越慢,硬件变得越来越便宜,越来越小。您需要一种不需要4个框架和2000个类即可完成任何有用操作的语言。
Go的设计没有内在的东西,这使其变得缓慢。但是,Go的设计师固有的某些特性使其比组装要慢:常识。


1
大多数(全部?)JIT在运行时进行编译,而不是在首次加载代码时进行编译。本机代码可能无法在所有的一些代码生成,并且也容易失效,例如,如果objsfor (obj : objs) { obj.meth() }有不同的实现方式meth,每次和JIT尝试内联它。当然,在通常情况下,所有这些实际上都是有益的,但仍然值得注意。

@delnan:V8在执行代码之前先对其进行编码。另外,LLVM是在考虑JITting的情况下构建的,因此(当然,需要付出一些努力)您可以及时进行任何优化,否则将在编译时进行优化。但是,某些优化(例如转义分析)只能与JIT一起使用。
back2dos

3
>>甚至没有说解决了哪些问题<<看,您会发现那些网页确实说了解决了哪些问题。实际上,您会找到程序源代码,构建命令,运行命令,语言实现版本,ya da ya da ya
igouy 2011年

10

我还注意到 Go在regex-dna基准测试中特别慢。拉斯•考克斯(Russ Cox)解释了为什么戈(Go)在这个特定的基准测试中表现欠佳。原因是Go的regexp软件包使用了不同的匹配算法,该算法在该特定基准测试中表现不佳,但在其他基准测试中可能要快很多。Ruby,Python和其他脚本语言也在使用另一种regexp匹配算法C实现

最后,计算机语言基准测试游戏包含可能无法准确反映所测语言的许多特征甚至无法调解错误印象的微基准测试。谷歌最近发表的这份研究论文更准确地概述了Go,Scala,Java和C ++的几种语言特性,尤其是“ V. Performance Analysis”部分。因此,最终Go几乎像Java(占Java内存的81%)一样耗费内存,甚至消耗了Scala的170%的内存(在本文中无法找到是否考虑了JVM的内存消耗)。

但是,Go仍然很年轻,并且仍处于开发阶段(API更改)!即将有许多改进。


3
>>此研究论文,最近由Google发表。<<这不是研究论文,也不由Google发表。这是一位Google员工在“ Scala Days 2011” Scala研讨会上发表的一份体验报告。
igouy 2011年

>>可能无法准确反映所测语言的许多特征,甚至不能调解错误的印象。<<就像“循环识别”程序一样,在不同编程语言之间的每次性能比较中也可能如此。事实上,作者告诉您-“我们不会探讨多线程或更高级别类型的机制的任何方面……我们也不会执行繁重的数值计算……”
igouy 2011年

@igouy在封面上,您可以阅读“ Google”,并且所有相关内容都包含相应的参考资料。那么,如果提及总部所在地的Google,为什么它不是“由Google发表的研究论文”呢?研究论文并非仅限于学术界。
亚历克斯(Alex)

在封面上,您可以阅读可以联系作者的邮寄地址,以及作者的电子邮件地址。检查您发布的pdf的URL。请注意域-days2011.scala-lang.org-Scala Days 2011“ Scala工作坊
。– igouy

1

Go比Python快,但比Java慢。我的粗略经验发现Go比Python快很多(1-2个数量级),比Java慢10-20%。但是,如果与四核(x64)一起使用,Go的速度将比Java稍快。就内存RAM而言,Go的效率也更高。

我想补充一点关于Go与Java和Python相比的性能潜力。Go可以执行C所做的更多工作,从而不断使C胜过大多数其他语言。对于高性能代码,避免缓存丢失非常重要。要减少高速缓存未命中,需要控制数据结构的内存布局。Go允许您执行此操作。Java并非没有,这使得避免内存和缓存碎片变得更加困难。

现在,Java运行通常比Go快,因为Java垃圾收集器要复杂得多。尽管没有理由说Go垃圾收集器再好不过了。目前,Java的代码生成可能也要好得多。Go具有很大的改进潜力,例如支持矢量指令等。

因此,我认为Go超越Java只是时间问题。尽管像使用任何语言一样,用Go编写代码都不会自动更快。您必须利用语言所提供的便利。我想说Go只是提供了更多调整代码的机会。

无论如何,那只是一个开发人员的经验。


4
这是一个有8年历史的问题,廉价的计算能力已使其变得无关紧要。您的答案还基于“您的感觉”,而不是硬数据。我不是要劝阻您,而是…
Kayaman
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.