英文:
why golang is slower than scala?
问题
在这个测试中,我们可以看到,Golang的性能有时比Scala慢得多。在我看来,由于Golang的代码直接编译成与C/C++兼容的二进制代码,而Scala的代码编译成JVM字节码,所以Golang的性能应该更好,特别是在这些计算密集型算法的基准测试中。我的理解是否不正确?
英文:
In this test, we can see that the performance of golang is sometimes much slower than scala. In my opinion, since the code of golang is compiled directly to c/c++ compatible binary code, while the code of scala is compiled to JVM byte code, golang should have much better performance, especially in these computation-intensive algorithm the benchmark did. Is my understanding incorrect?
<img src="http://benchmarksgame.alioth.debian.org/u64/chartvs.php?r=eNoljskRAEEIAlPCA48ozD%2Bb1dkX1UIhzELXeGcih5BqXeksDvbs8Vgi9HFr23iGiD82SgxJqRWkKNctgkMVUfwlHXnZWDkut%2BMK1nGawoYeDLlYQ8eLG1tvF91Dd8NVGm4sBfGaYo0Pok0rWQ%3D%3D&m=eNozMFFwSU1WMDIwNFYoNTNRyAMAIvoEBA%3D%3D&w=eNpLz%2FcvTk7MSQQADkoDKg%3D%3D" />
答案1
得分: 58
以下是我认为在四个基准测试中,Go解决方案相对于Scala解决方案最慢的原因:
-
mandelbrot:Scala实现将其内部循环展开了一次。可能是因为JVM可以像这样向量化计算,而Go编译器目前还不能做到。这是很好的手动优化,再加上JVM对加速算术运算的支持更好。
-
regex-dna:Scala实现没有按照基准测试要求进行操作:它被要求逐个匹配替换重定向文件中的模式,并记录序列长度,但它只是计算长度并打印出来。Go版本执行了匹配替换,因此较慢。
-
k-nucleotide:Scala实现通过使用位操作将核苷酸打包到长整型中进行了优化,而不是使用字符。这是一个很好的优化方法,也可以应用到Go代码中。
-
binary-trees:这个测试通过填充内存来测试垃圾回收性能。的确,Java的垃圾回收比Go的垃圾回收快得多,但不将其作为Go的首要任务的论点是,通常可以通过首先不产生垃圾来避免在真实程序中进行垃圾回收。
英文:
Here's what I think's going on in the four benchmarks where the go solutions are the slowest compared to the scala solutions.
- mandelbrot: the scala implementation has its internal loop unrolled one time. It may be also that the JVM can vectorise the calculation like this, which I think the go compiler doesn't yet do. This is good manual optimisation plus better JVM support for speeding arithmetic.
- regex-dna: the scala implementation isn't doing what the benchmark requires: it's asked to """(one pattern at a time) match-replace the pattern in the redirect file, and record the sequence length""" but it's just calculating the length and printing that. The go version does the match-replace so is slower.
- k-nucleotide: the scala implementation has been optimised by using bit-twiddling to pack nucleotides into a long rather than use chars. It's a good optimisation that could also be applied to the Go code.
- binary-trees: this tests gc performance by filling RAM. It's true that java gc is much faster than the go gc, but the argument for this not being the top priority for go is that usually one can avoid gc in real programs by not producing garbage in the first place.
答案2
得分: 20
这个图表来自编程对决。在参考这些基准测试结果之前,你应该先阅读对决页面上的免责声明。最多,这些基准测试只能用来指示性地了解性能的大致期望。
话虽如此,Java虚拟机(JVM)经过了十年的资金支持和优化,除了启动时间外,在运行代码时提供了出色的性能。Go语言仍然是一门年轻的语言。Go语言能够与JVM语言相媲美,这是令人印象深刻的。如果你喜欢用Go语言编程,不应该仅仅因为一个基准测试就否定它。
英文:
This chart is from the Programming Shootout. You should read the disclaimers on the Shootout page before taking the benchmarks as gospel. At best these benchmarks are only useful for indicating broad expectations of performance.
That said, the JVM has a decade of well-funded optimization and apart from startup time, provides excellent performance for running code. Go is still a young language. The fact that Go comes within spitting distance of a JVM language is impressive. If you enjoy programming in Go, you should not reject it over one benchmark.
答案3
得分: 15
这在Go的常见问题解答中有讨论:
>Go的设计目标之一是在可比较的程序中接近C的性能,但在一些基准测试中表现不佳,包括test/bench/shootout中的几个。最慢的基准测试依赖于在Go中没有可比性能版本的库。例如,pidigits.go依赖于一个多精度数学包,而C版本使用了GMP(它是用优化的汇编语言编写的)。依赖于正则表达式的基准测试(例如regex-dna.go)基本上是将Go的本地正则表达式包与成熟的、高度优化的正则表达式库(如PCRE)进行比较。
>基准测试的胜利需要进行广泛的调优,大多数基准测试的Go版本需要关注。如果你比较C和Go的可比程序(reverse-complement.go是一个例子),你会发现这两种语言在原始性能上比这个套件所示的要接近得多。
>尽管如此,还有改进的空间。编译器很好,但可以更好,许多库需要进行重大的性能工作,垃圾收集器还不够快。(即使它足够快,注意不生成不必要的垃圾可能会产生巨大的影响。)
另外,考虑一下给定编程语言的不同版本的基准测试之间的10倍(!)速度差异。C gcc #7比C gcc #5慢8.3倍,Ada #3比Ada #5慢近10倍。这些基准测试提供了一个大致的想法,即语言之间的差异,但Go和Scala之间的差异在一个数量级内,这意味着运行时之间的任何“固有”变化可能会被实现中的差异所掩盖:这篇文章描述了他们通过执行更智能的内存分配来将程序加速11倍。也许编译器/运行时应该自动处理这种优化(就像JVM在某种程度上做的那样),但我不确定你是否真的可以从这些数据中得出“Go比Scala慢(或快)”的结论。只是我的观点
英文:
This is discussed in the go FAQ:
>One of Go's design goals is to approach the performance of C for comparable programs, yet on some benchmarks it does quite poorly, including several in test/bench/shootout. The slowest depend on libraries for which versions of comparable performance are not available in Go. For instance, pidigits.go depends on a multi-precision math package, and the C versions, unlike Go's, use GMP (which is written in optimized assembler). Benchmarks that depend on regular expressions (regex-dna.go, for instance) are essentially comparing Go's native regexp package to mature, highly optimized regular expression libraries like PCRE.
>Benchmark games are won by extensive tuning and the Go versions of most of the benchmarks need attention. If you measure comparable C and Go programs (reverse-complement.go is one example), you'll see the two languages are much closer in raw performance than this suite would indicate.
>Still, there is room for improvement. The compilers are good but could be better, many libraries need major performance work, and the garbage collector isn't fast enough yet. (Even if it were, taking care not to generate unnecessary garbage can have a huge effect.)
As an aside, consider the 10x (!) speed difference between the different versions of a benchmark for a given programming language. C gcc #7 is 8.3 times slower than C gcc #5, and Ada #3 almost 10 times slower than Ada #5. These benchmarks provide a rough idea of how language compare, but the difference between Go and Scala is within one order of magnitude, which means any 'intrinsic' variation between the runtimes is likely to be dwarfed by differences in the implementation: this post describes how they sped up a program 11x by performing smarter memory allocation. Maybe the compiler/runtime should be handling this kind of optimisations automatically (as the JVM does, to a certain level), but I am not sure you can really draw the conclusion that 'Go is slower (resp. faster) than Scala' in the general case from these figures. Just my opinion though
答案4
得分: 11
由于你似乎对这些有偏见的基准测试很感兴趣。让我们以一个真实的例子来看一个真实的场景,而不是一些斐波那契实现。
请查看这些Web框架基准测试排名,测试是使用本机客户端(如果可用)和有时使用开源Web框架进行的,他们还使用许多软件包进行相同语言的测试。测试范围从对原始字符串的请求到使用ORM查询数据库。
很明显,Scala的性能远远不及Go,在所有测试中,Scala都低于Go。话虽如此,基准测试与现实情况相去甚远,我建议你从工具/功能的角度来看待一门语言,或者简单地考虑哪种语言最适合解决你的问题。
英文:
Since you seem to be keen in looking at these biased benchmarks. Let's take a real example for real scenario not some Fibonacci implementations.
Take a look at these rankings for web frameworks benchmarks, the testing was done using native client if available and sometimes using OSS web frameworks, they also use many packages for testing with the same language. The tests vary from requests for raw strings to using ORM to query a database.
It is clear that Scala performance is no where close to Go, in all of the tests Scala was below Go. Having said this, benchmarks are nothing close to reality and I suggest you look at a language from tools/features perspective or simply what would be best to solve your problem.
答案5
得分: 4
正如Brad所指出的,这些结果来自一个特定的基准测试套件。这提供了一些信息,但不要认为这就是全部。了解源代码在每种情况下是否编写得足够好以提供最快的速度、最少的内存使用量或其他目标目标将是有帮助的。
也许我们可以与另一个排名语言的网站进行比较。请查看http://www.techempower.com/benchmarks/,其中比较了Web服务代码。尽管是一种年轻的语言,Go在其中一些基准测试中是最好的之一。
就像所有的基准测试一样,它总是取决于你追求什么以及你如何衡量它。
英文:
As Brad pointed out, these results are from one particular benchmark suite. This provides some information, but don't assume it's the whole picture. It would be helpful to know whether the source code is well enough written in each case to give the fastest speed, the least memory use, or some other target goal.
Perhaps we might compare with another website that ranks languages. Take a look at http://www.techempower.com/benchmarks/ in which web service codes are compared. In spite of being a young language, Go is one of the best in some of these benchmarks.
As in all benchmarks, it always depends what you strive for and how you measure it.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论