Why is Go so slow (compared to Java)?
As we could see from The Computer Language Benchmarks Game in 2010:
- Go is on average 10x slower than C
- Go is 3x slower than Java !?
How can this be, bearing in mind that Go compiler produces native code for execution?
Immature compilers for Go? Or there is some intrinsic problem with the Go language?
EDIT:
Most answers deny intrinsic slowness of Go languge, claiming the problem resides in immature compilers.
Therefore I've made some own tests to calculate Fibonacci numbers: Iterative algorithm runs in Go (freebsd,6g) with the same
speed as in C (with O3 option). The dull recursive one runs in Go 2 times
slower than in C (with -O3 option; with -O0 - the same). But I haven't seen 10x fall as in the Benchmarks Game.
The 6g and 8g compilers are not particularly optimising, so the code they produce isn't particularly fast.
They're designed to run fast themselves and produce code that's OK (there is a bit of optimisation). gccgo
uses GCC's existing optimisation passes, and might provide a more pointful comparison with C, but gccgo isn't feature-complete yet.
Benchmark figures are almost entirely about quality of implementation. They don't have a huge amount to do with the language as such, except to the extent that the implementation spends runtime supporting language features that the benchmark doesn't really need. In most compiled languages a sufficiently clever compiler could in theory strip out what isn't needed, but there comes a point where you're rigging the demo, since very few real users of the language would write programs that didn't use that feature. Moving things out of the way without removing them entirely (e.g. predicting virtual call destinations in JIT-compiled Java) starts to get tricky.
FWIW, my own very trivial test with Go when I was taking a look at it (a loop of integer addition, basically), gccgo produced code towards the fast end of the range between gcc -O0
and gcc -O2
for equivalent C. Go isn't inherently slow, but the compilers don't do everything, yet. Hardly surprising for a language that's 10 minutes old.
In the next release of the Go FAQ, something similar to the following should appear.
Performance
Why does Go perform badly on benchmark X?
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. The slowest depend on libraries for which versions of comparable performance are not available in Go. For instance, pidigits 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, for instance) are essentially comparing Go's stopgap 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 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).
And here's some more details on The Computer Benchmarks Game from a recent mailing list thread.
Garbage collection and performance in gccgo (1)
Garbage collection and performance in gccgo (2)
It's important to note that the Computer Benchmarks Game is just a game. People with experience in performance measurement and capacity planning carefully match like with like over realistic and actual workloads; they don't play games.
My answer isn't quite as technical as everyone else's, but I think it's still relevant. I saw the same benchmarks on the Computer Benchmarks Game when I decided to start learning Go. But I honestly think all these synthetic benchmarks are pointless in terms of deciding whether Go is fast enough for you.
I had written a message server in Python using Tornado+TornadIO+ZMQ recently, and for my first Go project I decided to rewrite the server in Go. So far, having gotten the server to the same functionality as the Python version, my tests are showing me about 4.7x speed increase in the Go program. Mind you, I have only been coding in Go for maybe a week, and I have been coding in Python for over 5 years.
Go is only going to get faster as they continue to work on it, and I think really it comes down to how it performs in a real world application and not tiny little computational benchmarks. For me, Go apparently resulted in a more efficient program than what I could produce in Python. That is my take on the answer to this question.
Things have changed.
I think the current correct answer to your question is to contest the notion that go is slow. At the time of your inquiry your judgement was justified, but go has since gained a lot of ground in terms of performance. Now, it's still not as fast as C, but is no where near being 10x slower, in a general sense.
Computer language benchmarks game
At the time of this writing:
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%
Though, it does suffer brutally on the binary tree benchmark:
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%