The latest Go implementation (Go 1.7) has made Go a lot faster. I would argue that it closer the speed of executables generated with GCC (gcc/g++) than OpenJDK, the Oracle JVM, Mono or the .NET compiler for C#.
Go (the language) can be made just as fast as C (the language), for many cases. Go has the advantage of making it much easier to use multiple processors, though.
Conversely if you're using C/C++ through a ton of heap/virtual pointers then you're losing a lot of the value the language brings and should be using something higher level.
Because it exposes pointers as a first-class concept, you also have good control of how data is laid out in memory (=> locality).
It's not like Python or Java where everything is a pointer and gets spread out all over memory.
In also not a huge fan of a compiler "automatically" performing escape analysis. Makes a single change causing cascading perf problems very easy and hard to catch.
Escape analysis, like any such analysis, gets much more difficult in the presence of higher-order control flow. Currently the Go compilers punt on higher order control flow analysis. And Go uses higher-order control flow in spades, due to its heavy reliance on interfaces.
The end result is that lots of stuff is heap allocated.
> Java where everything is a pointer and gets spread out all over memory.
That's not true for Java. Its generational garbage collector performs bump allocation in the nursery, yielding tightly packed objects with excellent cache behavior. Allocation in HotSpot is like 3-5 instructions (really!)
I think the HotSpot approach makes the most sense: instead of trying to carve out special cases that fall down regularly, focus on making heap allocations fast, as you'll need to make them fast anyway. After that, add things like escape analysis (which HotSpot has as well).
When I see this link I get different impression.
http://mechanical-sympathy.blogspot.com/2012/10/compact-off-...
It is only heavy use of sun.misc.Unsafe and unidiomatic coding style that give Java semblance of memory efficiency.
Considering the popularity of memory compact Java collections like Fastutils etc I feel that memory bloat of standard Java is very common issue plaguing Java applications.
Actually, even Go isn't helping as much as it could here -- sometimes you want to have an array of objects that lays out each column (field) of memory contiguously, which Go gives you no easy way to do. But then neither does C or C++.
Isn't allocation just a couple instructions for basically GC languages?
If those GC'd languages have a precise generational GC with bump allocation in the nursery. Go doesn't (and the proposed GC design doesn't allow for this, unfortunately).
After previous implementation has made Go a lot slower.
Go 1.7 performs nowhere near the set of optimizations that GCC and LLVM do. GCC/LLVM have a huge number of algebraic simplifications (InstCombine), aggressive alias analysis, memory dependence analysis, instruction scheduling, an optimized instruction selector, a highly tuned register allocator with stuff like rematerialization, SCCP, etc. etc. It will take years and years for Golang to come close.
> Go (the language) can be made just as fast as C (the language), for many cases.
No, it can't. The M:N scheduling model will always have some overhead relative to 1:1 if you don't need the performance profile of C10K-style servers. The dynamic semantics of "defer" is an unavoidable performance tax over RAII. Unwinding is mandated by the language, inhibiting some optimizations. There is little control over allocation: language constructs allocate in ways that are not immediately obvious. The fact that interfaces result in huge numbers of virtual calls results in a good amount of overhead that (unlike Java) Go can't even eliminate with inline caching, because it's AOT compiled. This is just off the top of my head.
> Go has the advantage of making it much easier to use multiple processors, though.
Not really. Go's parallelism primitives are just as low-level as those of C. The "one size fits all" scheduling algorithm is a poor fit for getting the most performance out of multicore. The lack of generics is a real problem: it prevents you from using optimized concurrent data structures without paying the tax of interface{} or going through code generation hoops.
In any case, the lack of SIMD basically kills Go's applicability in these domains.
The only thing good about Go, is being an evolution path for C coders willing to embrace a GC and some type safety.
I now generally prefer Haskell.
Some magical built-in types (scalar, array, hash, typeglob, regexp, io handle) you cannot confuse, interface{} is scalar holding a reference, and built-in datatypes (arrays and hashes) are magical and you cannot construct something similar. Well, at least there's 'tie' mechanics in Perl after all that makes types extensible.
Type mismatch errors for basic types are handled in compile time, be it Go or Perl.
You say that like it's a small thing, but what proportion of bugs in C code does that cover? Im guessing you'd hit over 50%.
I just expected more from Google, specially if one compares to the other company sponsored languages.
Swift 3 looks good, though. They've learned the right lessons.
And Rust's traits are a far more principled (and thus better!) approach to overloading than anything C++ has (Boost's concept checks?). Traits turn concepts into language entities that are directly expressible in Rust syntax, rather than in awkward English documentation.
It's also fun when you don't realize a particular function has a default argument until you make a function pointer to it and assign/pass it to something that you mistakenly think is compatible. Depending on how nasty your codebase's use of templates and overloaded functions is, this can be a nightmare to debug.