39

Go is one of the few languages that are supposed to run 'close to the metal', i. e. it's compiled, statically typed and executes code natively, without a VM. This should give it a speed advantage over Java, C# and the like. It seems, however, that it's behind Java (see the Programming Language Shootout)

I'm assuming that less mature compilers are hugely responsible for this, but are there any other reasons? Is there anything inherent in Go's design that would prevent it from running faster than, say, Java? I have a very unsophisticated view of runtime models, but it seems that at least in principle it should be able to run faster than Java, thanks to native code execution.

Jonas
  • 14,867
  • 9
  • 69
  • 102
Greg Slodkowicz
  • 971
  • 2
  • 9
  • 11
  • 3
    Given a sufficently smart compiler (and/or VM, and/or JIT-compiler), a given language can always go faster (well, there are physical limitations, but that's it). This truism of course doesn't help anyone as long as this sufficently smart compiler isn't there. Note though that Java already has those sufficently smart implementations, and they're *incredibly* smart. Another fact of life is that the code run has at least as much influence on runtime performance as the implementation. –  Jun 14 '11 at 12:29
  • 1
    I understand that, but I was wondering if it's reasonable to expect Go's speed to match/overtake e. g. Java as it's compiler matures. – Greg Slodkowicz Jun 14 '11 at 12:33
  • 17
    Programming languages don't have a speed. Neither do language implementations. A given language implementation has a speed for some given input, and this speed can very greatly depending on the input. –  Jun 14 '11 at 12:34
  • 1
    I don't know that this question as asked can be answered. It seems unlikely that the Go compiler will ever have enough work done on it to outperform Java in a majority of generalized usage/input patterns but anything is possible. – Jeremy Jun 14 '11 at 15:50
  • 1
    There are three types of lies: lies, damned lies, and benchmarks. – Rein Henrichs Jun 14 '11 at 22:49
  • 1
    @delnan - Do you think there are many programmers who don't understand that their programs are run with a language implementation not a language? Perhaps we can be charitable and take that as a given. – igouy Jun 14 '11 at 23:29
  • @Rein Henrichs - "After all, facts are facts, and although we may quote one to another with a chuckle the words of the Wise Statesman, 'Lies--damned lies--and statistics,' still there are some easy figures the simplest must understand, and the astutest cannot wriggle out of." (Leonard Henry Courtney, 1895) – igouy Jun 14 '11 at 23:31
  • @ioguy: Given that so many people talk about a language being slow or fast, it seems that they at least assume the quality of the language implementation has a negible impact on the performance of a particular program. –  Jun 15 '11 at 12:19
  • 2
    @delnan - Or is it just a whole lot easier to say "Java" than to say "Java(TM) SE Runtime Environment (build 1.6.0_25-b06) Java HotSpot(TM) 64-Bit Server VM (build 20.0-b11, mixed mode)" :-) – igouy Jun 15 '11 at 16:21
  • @ioguy: Nobody needs that much detail. But once the discussion gets serious, I expect eveyone who fully realizes the difference to make a distinction between different implementations. Java isn't the best example here, as there isn't much discrepancy between most JVMs nowadays - a better example might be JS or Python, which have slow interpreters and smart JITs. A post discussing the "Performance of {JS, Python}" must talk about the wildly different implementations or it's grossly oversimplifying (not necessarily wrong, as not even PyPy or V8 will likely beat C in real-world applications). –  Jun 15 '11 at 16:58
  • 1
    @delnan >>Java isn't the best example here<< Greg Slodkowicz asked about Go, Java and C# - and you chose to correct him. – igouy Jun 15 '11 at 18:05
  • @ioguy: Java isn't the best example for showing how "language in practice" and "language implementation" makes a difference. But even apart from that, my personal experience so far has been that those who really know what they're talking about (give comprehensive, correct, balanced summaries of performance characteristics) do bother to mention individual implementations and/or implementation techniques while the hardly enlightening "L1 is slow, L2 is fast" statements (no better than "X sucks, Y rules" IMHO) don't seem aware of differences between implementations. –  Jun 15 '11 at 19:10
  • @ioguy: But apart from all that, my main point is and was: Go is just a language, it depends mostly on the implementations how fast a given program runs. Whether or not future implementations can run a significant amount of useful programs as fast as e.g. JVMs can run equivalent Java programs is hardly predicatable, just like it isn't really predictable if MS Word 2016 will have more features than an OpenOffice release from the same month. –  Jun 15 '11 at 19:14

4 Answers4

46

In terms of language design, there isn't really anything that should make Go slower than Java in general. In fact, it gives you more control of the memory layout of your data structures, so for a lot of common tasks it should be somewhat faster. However, the current primary Go compiler, scheduler, garbage collector, regexp library, and a lot of other things aren't particularly optimized. This is steadily improving, but the focus seems to be on being useful, simple, and fast enough over winning in microbenchmarks.

In the linked benchmark, Go loses big to Java on the binary tree and the regexp test. Those are tests of the memory management system and regexp library respectively. Go's memory management could be faster and will certainly improve over time, and the current standard regexp library is a placeholder for a much better implementation that is soon to come. So, losing on those two isn't surprising, and in the near future the margin should be more narrow.

For the k-nucleotide benchmark, it's somewhat hard to compare because the Java code looks to be using a different algorithm. The Go code will certainly benefit from compiler, scheduler, and allocator improvements to come, even as written, but someone would have to rewrite the Go code to do something more clever if we wanted to compare more accurately.

Java wins in the mandelbrot benchmark because it's all floating point arithmetic and loops, and this is a great place for the JVM to generate really good machine code and hoist things at runtime. Go, in comparison, has a pretty simple compiler that doesn't hoist, unroll, or generate really tight machine code currently, so it's not surprising it loses. However, one should keep in mind that the Java timing doesn't count the JVM start-up time or the many times it needs to be run for the JVM to JIT it nicely. For long-running programs, this isn't relevant, but it matters in some cases.

As for the rest of the benchmarks, Java and Go are basically neck-in-neck, with Go taking significantly less memory and in most cases less code. So, while Go is slower than Java in a number of those tests, Java is pretty fast, Go does pretty well in comparison, and Go will probably get notably faster in the near future.

I'm looking forward to when gccgo (a Go compiler that uses the gcc codegen) is mature; that should make Go pretty much in line with C for many types of code, which will be interesting.

Kyle C
  • 668
  • 5
  • 5
22
  1. Without even saying which problems were solved, the whole benchmark is pointless.
  2. JVM and CLR both use JITs to produce machine code. There's no reason this should be slower. It just costs you ages to boot.
  3. Go was designed to build fast. You don't have tons of compile time and boot time optimizations. Go compiles its own standard library by the time a Java app has booted.

Could Go be faster at runtime? Yes. Will Go ever be faster at runtime? I don't know. Maybe the compiler builders will add optional optimization at the cost of compile time. But I don't think they have much interest in that. They work at Google.
What they want is a language that allows fast development and that performs good at what they do. Hell, even if that benchmark was credible, it would mean they are half as fast as C and 14 times as fast as Python. This is more than good enough.
Hardware is cheap, code is expensive. Code tends to become bigger and slower as you invest money, hardware becomes cheaper and smaller. You want a language, that doesn't require 4 frameworks and 2000 classes to accomplish anything useful.
There's nothing inherent in Go's design, that makes it slow. However there's something inherent in Go's designers, that makes it slower than assembly: common sense.

back2dos
  • 29,980
  • 3
  • 73
  • 114
  • 1
    Most (all?) JITs compile during runtime, not when the code is first loaded. This machine code may not be generated at all for some code and can also easily be invalidated, e.g. if the `objs` in `for (obj : objs) { obj.meth() }` have different implementations of `meth` every time and the JIT tries to inline it. Of course, all this is *actually a benefit* in the common cases, but still notesworthy. –  Jun 14 '11 at 12:59
  • @delnan: The [V8](http://en.wikipedia.org/wiki/V8_(JavaScript_engine)) JITs any code before executing it. Also, the LLVM was built with JITting in mind, therefore (with some effort of course) you can do any optimization just in time, that would otherwise happen at compile time. However, certain optimizations, such as escape analysis only really work with JITs. – back2dos Jun 14 '11 at 15:20
  • 3
    >>Without even saying which problems were solved<< Look and you'll find that those web pages DO say which problems were solved. In fact, you'll find program source code, build commands, run commands, language implementation version, *ya da ya da ya* – igouy Jun 14 '11 at 23:33
10

I've also noticed that Go was particularly slow in the regex-dna benchmark. Russ Cox explained why Go wasn't that performant in this particular benchmark. The reason is that Go's regexp package is using a different matching algorithm that performs bad in this particular benchmark but might be by a magnitudes faster in other benchmarks. Also Ruby, Python and other scripting languages are using a C implementation of another regexp matching algorithm.

Finally the Computer Language Benchmarks Game consists of micro-benchmarks that might not accurately reflect many characteristics of the measured languages and even mediate wrong impressions. This research paper, recently published by Google gives a more accurate overview of several language characteristics of Go, Scala, Java and C++ — particularly the "V. Performance Analysis" part. So in the end Go's almost as memory-hungry as Java (81% of Java's memory) and consumes even 170% as much memory as Scala (couldn't find in the paper whether JVM's memory consumption was considered).

But again, Go's young and still under heavy development (API changes)! Many improvements are coming soon.

Alex
  • 201
  • 1
  • 5
  • 3
    >>This research paper, recently published by Google<< It isn't a research paper, and it wasn't published by Google. It's an experience report by one Google employee presented at the "Scala Days 2011" Scala workshop. – igouy Jun 15 '11 at 17:49
  • >>might not accurately reflect many characteristics of the measured languages and even mediate wrong impressions<< That's just as true of the "loop recognition" programs, and likely to be true of every performance comparison between different programming languages. In fact the author tells you - "We do not explore any aspects of multi-threading, or higher level type mechanisms... we also do not perform heavy numerical computation..." – igouy Jun 15 '11 at 17:58
  • @igouy On the cover you can read "Google" and everything relevant is covered with corresponding references. So why it's not a "research paper, published by Google" if Google is mentioned with its headquarter address? Research papers aren't an academia-only domain. – Alex Jun 15 '11 at 21:41
  • On the cover you can read the mailing address at which the author can be contacted, and the author's email address. Check the URL of the pdf that you posted. Note the domain - days2011.scala-lang.org - the Scala Days 2011" Scala workshop. – igouy Jun 16 '11 at 16:05
1

Go is faster than Python and a little slower than Java. My rough experience has found Go to be much (1-2 orders of magnitude) faster than Python, and about 10-20% slower than Java. However, Go is slightly faster than Java if it used with quad-core (x64). Go also is a lot more efficient in the terms of memory RAM.

I'd like to add some points about Go's potential for performance vs Java and Python. Go allows more of the things that C does which constantly allows C to outperform most other languages. Cache misses are quite important to avoid for high performance code. Reducing cache misses requires controlling the memory layout of your data structures. Go allows you to do that. Java doesn't which makes it harder to avoid fracturing of memory and cache.

Right now Java usually runs faster than Go, because Java garbage collector is a lot more sophisticated. Although there is not reason the Go garbage collector couldn't be a lot better. Code generation is also likely a lot better for Java at the moment. Go has a lot of potential to improve e.g. with support for vector instructions etc.

So I think it is really just a question of time before Go edges past Java. Although like with any language code isn't likely going to be faster automatically by being written in Go. You have to utilize the facilities the language gives you. I'd say Go simply gives more opportunities to tune your code.

Anyway, that's just one developer's experience.

Glorfindel
  • 3,137
  • 6
  • 25
  • 33
Isacc Barker
  • 119
  • 2
  • 4
    This is an 8 year old question and cheap computing power has made it pretty much irrelevant. Your answer is also based on "your feeling" rather than hard data. I don't mean to discourage you, but... – Kayaman Jun 28 '19 at 04:06