Why is Go so slow (compared to Java)?

JavaPerformanceGoBenchmarking

Java Problem Overview


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.

Java Solutions


Solution 1 - Java

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.

Solution 2 - Java

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.

Solution 3 - Java

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.

Solution 4 - Java

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%

Solution 5 - Java

Despite the not so good efficiency of Go about the CPU cycles usage, the Go concurrency model is much faster than the thread model in Java, for instance, and can be comparable to C++ thread model.

Note that in the thread-ring benchmark, Go was 16x faster than Java. In the same scenario Go CSP was almost comparable to C++, but using 4x less memory.

The great power of Go language is its concurrency model, Communicating Sequential Processes, CSP, specified by Tony Hoare in 70's, being simple to implement and fit for highly concurrent needs.

Solution 6 - Java

There are two basic reasons that that Java is faster than Go and C++, and can be faster than C in many cases:

  1. The JIT compiler. It can inline virtual function calls through multiple levels, even with OO classes, based on the runtime profile. This is not possible in a statically compiled language (although the newer re-compilation based on recorded profile can help). This is very important to most benchmarks that involve repetitive algorithms.

  2. The GC. GC based memory allocation is nearly free, as compared to malloc. And the 'free' penalty can be amortized across the entire runtime - often skipped because the program terminates before all garbage needs to be collected.

There are hundreds (thousands?) of extremely talented developers making the GC/JVM efficient. Thinking you can "code better than all of them" is a folly. It is a human ego problem at its heart - humans have a hard time accepting that with proper training by talented humans, the computer is going to perform better than the humans that programmed it.

Btw, C++ can be as fast as C if you don't use and of the OO features, but then you are pretty close to just programming in C to begin with.

Most importantly, the "speed differences" in these tests are usually meaningless. The IO costs are orders of magnitude more than the performance differences, and so proper designs that minimize IO costs always win - even in a interpreted language. Very few systems are CPU bound.

As a final note, people refer to the "computer language benchmarks game" as a "scientific measure". The tests are completely flawed, For example, if you view the Java tests for nbody. When I run the tests on the same OS/hardware, I get roughly 7.6 secs for Java, and 4.7 secs for C - which is reasonable - not the 4x slowness the tests reports. It is click-bait, fake news, designed to generate site traffic.

As a final, final note... I ran the tests using Go, and it was 7.9 secs. The fact that when you click on Go, it compares it to Java, and when you click on Java it compares it to C, should be a red flag to any serious engineer.

For a real world comparison of Java, Go, and C++ see https://www.biorxiv.org/content/10.1101/558056v1 spoiler alert, Java comes out on top in raw performance, with Go coming out on top with combined memory use and wall time.

Solution 7 - Java

I think an often overlooked fact is, that JIT compilation can be > static compilation especially for (runtime) late bound functions or methods. The hotspot JIT decides at RUNTIME which methods to inline, it even might adjust data layout to the cache size/architecture of the CPU it is currently running on. C/C++ in general can make up (and overall will still perform better) by having direct access to the hardware. For Go things might look different as its more high-level compared to C, but currently lacks a runtime optimization system/compiler. My gut tells me, Go could be faster then Java as Go does not enforce pointer chasing that much and encourages better data structure locality + requires less allocation.

Solution 8 - Java

As a matter of fact, Go is not only elegant and efficient at design time, but also super performant at run-time. The key is to use the right operating system i.e. LINUX. Performance profiling result under Windows and Mac OS are, for lack of a better word, one or two orders of magnitude inferior.

Solution 9 - Java

under linux, the go runtime is super fast, perfectly comparable with c/c++. the go runtime under windows and unix are not in the same league

comparison with java is not so important, go is for both system and application development (as java is more like blue collar for application development only). will not enter in details, but when things like kubernetes are written in go, you realize that is not an enterprise consultant friendly toy

i do not remember google mentioning even once about the compromise you refer to. go is well design, simple, elegant and efficient for for designing system and application level programs, has pointers, efficient memory allocation and deallocation, avoids complications arising from oh so easy to miss-use implementation inheritance, giving you co-routines and other modern ways to write high performance applications in time and budget. again, go is super fast under linux, which is exactly what it was designed for (very happy that it does)

Solution 10 - Java

Both Java and C are more explicit with their data and method (function) definitions. C is statically typed, and Java is less so with its inheritance model. This means that the way the data will be handled is pretty much defined during the compilation.

Go is more implicit with its data and function definitions. The built in functions are more general in nature, and the lack of a type hierarchy (like Java or C++) gives Go a speed disadvantage.

Keep in mind that Google's goal for the Go language is to have an acceptable compromise between speed of execution and speed of coding. I think they are hitting a good sweet spot on their early attempt, and things will only improve as more work is done.

If you compare Go with more dynamically typed languages whose main advantage is speed of coding, you will see the execution speed advantage of Go. Go is 8 times faster than perl, and 6 times faster than Ruby 1.9 and Python 3 on those benchmarks you used.

Anyway the better question to ask is Go a good compromise in ease of programming versus speed of execution? My answer being yes and it should get better.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionOleg RazgulyaevView Question on Stackoverflow
Solution 1 - JavaSteve JessopView Answer on Stackoverflow
Solution 2 - JavapeterSOView Answer on Stackoverflow
Solution 3 - JavajdiView Answer on Stackoverflow
Solution 4 - JavatiffonView Answer on Stackoverflow
Solution 5 - JavaDLopesView Answer on Stackoverflow
Solution 6 - Javauser9778120View Answer on Stackoverflow
Solution 7 - JavaR.MoellerView Answer on Stackoverflow
Solution 8 - JavaDan MarinescuView Answer on Stackoverflow
Solution 9 - JavaDan MarinescuView Answer on Stackoverflow
Solution 10 - JavaBill CView Answer on Stackoverflow