正如我们从2010年的计算机语言基准游戏中看到的那样:
Go平均比C慢10倍
Go比Java慢3倍!
考虑到Go编译器生成用于执行的本机代码,这怎么可能呢?
Go的不成熟的编译器?或者Go语言存在一些内在问题?
编辑:
大多数答案否认Go语言的内在缓慢,声称问题存在于不成熟的编译器中.
因此,我已经做了一些自己的测试来计算Fibonacci数:迭代算法在Go(freebsd,6g)中运行,same
速度与C相同(使用O3选项).沉闷的递归运行在Go中2 times
比在C中慢(使用-O3选项;使用-O0 - 相同).但我没有看到基准游戏中的10倍跌幅.
6g和8g编译器没有特别优化,因此它们生成的代码不是特别快.
它们被设计为自己快速运行并生成可以正常运行的代码(有一些优化).gccgo
使用GCC现有的优化通道,可能会提供与C更有意义的比较,但gccgo尚未完成功能.
基准数据几乎完全与实施质量有关.它们与语言本身并没有太大关系,除非实现花费运行时支持基准测试并不真正需要的语言功能.在大多数编译语言中,一个足够聪明的编译器理论上可以删除不需要的东西,但是有一个点你需要操作演示,因为很少有真正的语言用户会编写没有使用该功能的程序.在不完全删除它们的情况下将事物移开(例如,在JIT编译的Java中预测虚拟调用目标)开始变得棘手.
FWIW,当我看一下它(基本上是一个整数加法的循环)时,我用Go进行的非常简单的测试,gccgo生成的代码朝向范围之间的快速结束gcc -O0
和gcc -O2
等效的C. Go本身并不慢,但编译器并没有做任何事情.对于一种10分钟的语言来说,这简直令人惊讶.
在Go FAQ的下一个版本中,应该出现类似于以下内容的内容.
性能
为什么Go在基准X上表现不佳?
Go的设计目标之一是为可比较的程序接近C的性能,但在某些基准测试中,它的表现相当差,包括测试/工作台中的几个.最慢的依赖于库,Go中没有可用性能相当的库.例如,pidigits依赖于多精度数学包,而C版本与Go不同,使用GMP(用优化的汇编程序编写).依赖于正则表达式(正则表达式-DNA,例如)基准基本上比较Go的权宜之计正则表达式包走向成熟一样PCRE,高度优化的正则表达式库.
通过广泛的调整赢得基准游戏,大多数基准测试的Go版本需要引起注意.如果你测量可比较的C和Go程序(反向补充是一个例子),你会发现两种语言的原始性能比这个套件所表明的要接近得多.
不过,还有改进的余地.编译器很好但可能更好,许多库需要主要的性能工作,垃圾收集器还不够快(即使它是,注意不要产生不必要的垃圾会产生巨大的影响).
以下是最近邮件列表主题中关于计算机基准游戏的更多详细信息.
gccgo的垃圾收集和性能(1)
gccgo的垃圾收集和性能(2)
值得注意的是,计算机基准游戏只是一款游戏.具有性能测量和容量规划经验的人员可以像现实和实际工作负载一样仔细匹配; 他们不玩游戏.
我的回答并不像其他人那样技术性,但我认为它仍然具有相关性.当我决定开始学习Go时,我在计算机基准游戏中看到了相同的基准.但老实说,我认为所有这些综合基准测试在决定Go是否足够快的方面毫无意义.
我最近使用Tornado + TornadIO + ZMQ在Python中编写了一个消息服务器,对于我的第一个Go项目,我决定在Go中重写服务器.到目前为止,让服务器具有与Python版本相同的功能,我的测试向我展示了Go程序中4.7倍的速度提升.请注意,我只在Go中编写了一个星期的代码,而且我已经用Python编写了超过5年的编码.
Go只会在它们继续工作时变得更快,我认为它实际上归结为它在现实世界的应用程序中的表现,而不是微小的计算基准.对我来说,Go显然比我在Python中生成的程序更有效.这是我对这个问题的回答.
事情变了。
我认为当前对您问题的正确答案是反驳“走慢”的概念。在您询问时,您的判断是有道理的,但是go在性能方面有了很多基础。现在,它仍然不如C快,但从一般意义上讲,它的速度要慢10倍。
计算机语言基准测试游戏
在撰写本文时:
source secs KB gz cpu cpu load reverse-complement 1.167x Go 0.49 88,320 1278 0.84 30% 28% 98% 34% C gcc 0.42 145,900 812 0.57 0% 26% 20% 100% pidigits 1.21x Go 2.10 8,084 603 2.10 0% 100% 1% 1% C gcc 1.73 1,992 448 1.73 1% 100% 1% 0% fasta 1.45x Go 1.97 3,456 1344 5.76 76% 71% 74% 73% C gcc 1.36 2,800 1993 5.26 96% 97% 100% 97% regex-dna 1.64x Go 3.89 369,380 1229 8.29 43% 53% 61% 82% C gcc 2.43 339,000 2579 5.68 46% 70% 51% 72% fannkuch-redux 1.72x Go 15.59 952 900 62.08 100% 100% 100% 100% C gcc 9.07 1,576 910 35.43 100% 99% 98% 94% spectral-norm 2x Go 3.96 2,412 548 15.73 99% 99% 100% 99% C gcc 1.98 1,776 1139 7.87 99% 99% 100% 99% n-body 2.27x Go 21.73 952 1310 21.73 0% 100% 1% 2% C gcc 9.56 1,000 1490 9.56 1% 100% 1% 1% k-nucleotide 2.40x Go 15.48 149,276 1582 54.68 88% 97% 90% 79% C gcc 6.46 130,076 1500 17.06 51% 37% 89% 88% mandelbrot 3.19x Go 5.68 30,756 894 22.56 100% 100% 99% 99% C gcc 1.78 29,792 911 7.03 100% 99% 99% 98%
但是,它在二叉树基准测试中确实遭受了残酷的折磨:
binary-trees 12.16x Go 39.88 361,208 688 152.12 96% 95% 96% 96% C gcc 3.28 156,780 906 10.12 91% 77% 59% 83%
尽管围绕CPU周期使用效率不是很高,但Go并发模型比Java中的线程模型快得多,并且可以与C++线程模型相媲美.
请注意,在线程环基准测试中,Go 比Java快16倍.在相同的场景中,Go CSP几乎与C++相当,但使用的内存减少了4倍.
Go语言的强大功能是它的并发模型,通信顺序进程,CSP,由Tony Hoare在70年代指定,易于实现并适合高度并发的需求.