为什么Go这么慢(与Java相比)?

2022-08-31 09:18:31

正如我们从2010年的计算机语言基准游戏中看到的:

  • Go平均比C慢10倍
  • Go比Java慢3倍!?

考虑到Go编译器会生成用于执行的本机代码,这怎么可能呢?
Go的不成熟编译器?或者Go语言存在一些内在问题?

编辑:
大多数答案都否认Go语言的内在缓慢,声称问题存在于不成熟的编译器中。
因此,我做了一些自己的测试来计算斐波那契数列:迭代算法在Go(freebsd,6g)中运行,速度与C(使用O3选项)相同。沉闷的递归在 Go 中比在 C 中运行得慢(使用 -O3 选项;使用 -O0 - 相同)。但我还没有看到像基准测试游戏那样下降10倍。same2 times


答案 1

6g和8g编译器不是特别优化,因此它们生成的代码不是特别快。

它们旨在自己快速运行并生成可以运行的代码(有一些优化)。 使用GCC现有的优化通道,并可能提供与C更有意义的比较,但gccgo的功能尚未完成。gccgo

基准数字几乎完全是关于实施质量的。它们与语言本身没有太大关系,除非实现花费在运行时支持基准测试并不真正需要的语言功能上。在大多数编译语言中,一个足够聪明的编译器理论上可以剥离不需要的东西,但是有一个点是你正在操纵演示,因为很少有该语言的真正用户会编写不使用该功能的程序。在不完全删除它们的情况下将事物移开(例如,在JIT编译的Java中预测虚拟呼叫目的地)开始变得棘手。

FWIW,我自己对Go的非常微不足道的测试,当我看它时(基本上是整数加法的循环),gccgo在等效C之间的范围的快速末尾生成代码。Go本身并不慢,但编译器还没有做所有事情。对于一门10分钟前的语言来说,这并不奇怪。gcc -O0gcc -O2


答案 2

在下一版本的 Go 常见问题解答中,应出现类似于以下内容的内容。

性能

为什么 Go 在基准测试 X 上表现不佳?

Go的设计目标之一是接近C在可比程序的性能,但在一些基准测试中,它的表现相当差,包括测试/工作台中的几个。最慢的取决于哪些库在 Go 中没有可比性能的版本。例如,pidigits依赖于多精度数学包,而C版本与Go不同,使用GMP(用优化的汇编程序编写)。依赖于正则表达式(例如正则表达式-dna)的基准测试本质上是将 Go 的权宜之计包与成熟、高度优化的正则表达式库(如 PCRE)进行比较。

基准测试游戏是通过广泛的调整赢得的,大多数基准测试的围棋版本需要注意。如果你测量可比较的C和Go程序(反向补码就是一个例子),你会看到这两种语言在原始性能上比这个套件所显示的要接近得多。

尽管如此,仍有改进的余地。编译器很好,但可能会更好,许多库需要大量的性能工作,而且垃圾回收器还不够快(即使它是,注意不要生成不必要的垃圾会产生巨大的影响)。

以下是有关计算机基准测试游戏的更多详细信息,来自最近的邮件列表线程。

gccgo 中的垃圾回收和性能 (1)

gccgo 中的垃圾回收和性能 (2)

重要的是要注意,计算机基准测试游戏只是一个游戏。具有性能测量和容量规划经验的人员在现实和实际工作负载上仔细匹配;他们不玩游戏。


推荐