Google Go 的性能如何?
那么有人用过Google的Go吗?我想知道与其他具有垃圾收集器的语言(例如 Java 或 .NET)相比,其数学性能(例如失败次数)如何?
有人调查过这个吗?
So has anyone used Google's Go? I was wondering how the mathematical performance (e.g. flops) is compared to other languages with a garbage collector... like Java or .NET?
Has anyone investigated this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
Go 数学包主要是为了性能而用汇编语言编写的。
基准通常不可靠并且可能会受到解释。例如,Robert Hundt 的论文C++/Java/Go/Scala 中的循环识别看起来有缺陷。关于分析 Go 程序的 Go 博客文章剖析了 Hundt 的主张。
The Go math package is largely written in assembler for performance.
Benchmarks are often unreliable and are subject to interpretation. For example, Robert Hundt's paper Loop Recognition in C++/Java/Go/Scala looks flawed. The Go blog post on Profiling Go Programs dissects Hundt's claims.
您实际上是在问几个不同的问题。首先,Go 的数学性能将与其他任何东西一样快。任何编译为本机代码的语言(甚至可以说包括 .NET 等 JIT 语言)在原始数学方面都将表现得非常好——与机器的运行速度一样快。简单的数学运算很容易编译成零开销的形式。这是编译(包括 JIT)语言比解释语言具有优势的领域。
您问的另一个问题是关于垃圾收集的。从某种程度上来说,如果你谈论的是繁重的数学,这只是一个次要问题。这并不是说 GC 不会影响性能——实际上它影响很大。但紧密循环的常见解决方案是避免或最小化 GC 扫描。如果您正在执行紧密循环,这通常非常简单 - 您只需重新使用旧变量,而不是不断分配和丢弃它们。这可以将代码速度提高几个数量级。
至于 GC 实现本身——Go 和 .NET 都使用标记和清除垃圾收集。微软在他们的 GC 引擎上投入了大量的精力和工程,我不得不认为,从各方面考虑,它都非常好。 Go 的 GC 引擎是一项正在进行中的工作,虽然它感觉并不比 .NET 的架构慢,但 Golang 人员坚持认为它需要一些工作。事实上,Go 的规范不允许析构函数,这对加快速度有很大帮助,这可能就是为什么它看起来并不那么慢的原因。
最后,根据我自己的轶事经验,我发现 Go 非常快。我编写了非常简单易用的程序,这些程序在我自己的基准测试中与来自一些长期存在且备受推崇的开源项目的高度优化的 C 代码相比较,这些项目以性能为荣。
问题是并非所有 Go 代码都是高效的,就像并非所有 C 代码都是高效的一样。您必须正确构建它,这通常意味着以不同于您习惯的其他语言的方式做事。这里多次提到的分析博客文章就是一个很好的例子那。
You're actually asking several different questions. First of all, Go's math performance is going to be about as fast as anything else. Any language that compiles down to native code (which arguably includes even JIT languages like .NET) is going to perform extremely well at raw math -- as fast as the machine can go. Simple math operations are very easy to compile into a zero-overhead form. This is the area where compiled (including JIT) languages have a advantage over interpreted ones.
The other question you asked was about garbage collection. This is, to a certain extent, a bit of a side issue if you're talking about heavy math. That's not to say that GC doesn't impact performance -- actually it impacts quite a bit. But the common solution for tight loops is to avoid or minimize GC sweeps. This is often quite simple if you're doing a tight loop -- you just re-use your old variables instead of constantly allocating and discarding them. This can speed your code by several orders of magnitude.
As for the GC implementations themselves -- Go and .NET both use mark-and-sweep garbage collection. Microsoft has put a lot of focus and engineering into their GC engine, and I'm obliged to think that it's quite good all things considered. Go's GC engine is a work in progress, and while it doesn't feel any slower than .NET's architecture, the Golang folks insist that it needs some work. The fact that Go's specification disallows destructors goes a long way in speeding things up, which may be why it doesn't seem that slow.
Finally, in my own anecdotal experience, I've found Go to be extremely fast. I've written very simple and easy programs that have stood up in my own benchmarks against highly-optimized C code from some long-standing and well-respected open source projects that pride themselves on performance.
The catch is that not all Go code is going to be efficient, just like not all C code is efficient. You've got to build it correctly, which often means doing things differently than what you're used to from other languages. The profiling blog post mentioned here several times is a good example of that.
Google 做了一项研究,将 Go 与其他一些流行语言(C++、Java、Scala)进行比较。他们得出的结论是,它在性能方面并不那么强大:
https: //days2011.scala-lang.org/sites/days2011/files/ws3-1-Hundt.pdf
引用关于 Go 的结论:
Google did a study comparing Go to some other popular languages (C++, Java, Scala). They concluded it was not as strong performance-wise:
https://days2011.scala-lang.org/sites/days2011/files/ws3-1-Hundt.pdf
Quote from the Conclusion, about Go:
理论性能:纯Go程序的理论性能介于C/C++和Java之间。这假设有一个高级优化编译器,并且还假设程序员利用该语言的所有功能(无论是 C、C++、Java 还是 Go)并重构代码以适应编程语言。
实际性能(截至2011年7月):标准Go编译器(5g/6g/8g)目前无法生成高性能数值代码的高效指令流,因此性能会低于C/C++或Java。造成这种情况的原因有多种:每个函数调用都会有一些额外指令的开销(与 C/C++ 或 Java 相比)、无函数内联、平均质量的寄存器分配、平均质量的垃圾收集器、擦除边界的能力有限检查、无法访问 Go 中的向量指令、编译器不支持 32 位 x86 CPU 上的 SSE2 等。
底线:根据经验,预计在纯 Go 中实现的数字代码的性能,由5g/6g/8g,比C/C++或Java低2倍。期待未来的表现会有更好的表现。
实际性能(2013 年 9 月):与 2011 年 7 月的旧版 Go 相比,Go 1.1.2 能够生成更高效的数字代码,但它们的运行速度仍然比 C/C++ 和 Java 稍慢。即使在 32 位 x86 CPU 上,编译器也使用 SSE2 指令,这使得 32 位数字代码运行得更快,这很可能归功于更好的寄存器分配。编译器现在实现了函数内联和转义分析。垃圾收集器也得到了改进,但仍然不如 Java 的垃圾收集器先进。仍然不支持从 Go 访问向量指令。
底线:性能差距似乎足够小,足以让 Go 在数值计算中成为 C/C++ 和 Java 的替代品,除非竞争的实现使用向量指令。
Theoretical performance: The theoretical performance of pure Go programs is somewhere between C/C++ and Java. This assumes an advanced optimizing compiler and it also assumes the programmer takes advantage of all features of the language (be it C, C++, Java or Go) and refactors the code to fit the programming language.
Practical performance (as of July 2011): The standard Go compiler (5g/6g/8g) is currently unable to generate efficient instruction streams for high-performance numerical codes, so the performance will be lower than C/C++ or Java. There are multiple reasons for this: each function call has an overhead of a couple of additional instructions (compared to C/C++ or Java), no function inlining, average-quality register allocation, average-quality garbage collector, limited ability to erase bound checks, no access to vector instructions from Go, compiler has no support for SSE2 on 32-bit x86 CPUs, etc.
Bottom line: As a rule of thumb, expect the performance of numerical codes implemented in pure Go, compiled by 5g/6g/8g, to be 2 times lower than C/C++ or Java. Expect the performance to get better in the future.
Practical performance (September 2013): Compared to older Go from July 2011, Go 1.1.2 is capable of generating more efficient numerical codes but they remain to run slightly slower than C/C++ and Java. The compiler utilizes SSE2 instructions even on 32-bit x86 CPUs which causes 32-bit numerical codes to run much faster, most likely thanks to better register allocation. The compiler now implements function inlining and escape analysis. The garbage collector has also been improved but it remains to be less advanced than Java's garbage collector. There is still no support for accessing vector instructions from Go.
Bottom line: The performance gap seems sufficiently small for Go to be an alternative to C/C++ and Java in numerical computing, unless the competing implementation is using vector instructions.