Is Golang really a competitor to C++ ?
How similar is GO to C?
Why is Golang not as performant as C or C++?
Some people like to blame all of the slowness of languages like Go, C#, and Java on garbage collection, but that isn't a very complete story. People will correctly tell you that normally garbage collection takes up a very very small % of total runtime, and that is true, so what else is going on? There are some indirect and related things as well.
-
Languages that have garbage collection are attempting to be memory safe languages, so:
-
They will also tend to have array bounds checks when the compiler can't prove they can be elided
-
They will tend not to allow as many clever casts
-
They will tend not to allow pointer arithmetic
-
Providing ways to leverage SIMD instructions by hand is hard (Go gives access only through Go assembler at the moment)
-
They will tend not to have a way for the compiler to do floating point optimizations that can change results like --ffast-math in C compilers
-
-
Garbage Collection has some indirect effects aside from how much time is spent doing GC
-
Every time the GC runs it pollutes the CPU caches, slowing down code that runs later
-
GC will normally imply a degree of overhead when doing FFI (interop with other languages). Go has even more overhead due to how it manages it's stack, which facilitates goroutine features. Lots of things require FFI still (3d rendering, for example) so those things will always be slower.
-
The control you get over memory layout of your data is usually limited to some degree. For instance in Go you can't explicitly control whether data goes on the stack, or heap, or *where* to goes on the heap. On the bright side in Go you can at least work with any type you create as a value or a reference, so you can at least control things like making sure your array is an array of values in contiguous memory vs an array of references, which you can't in Java. Accessing RAM is very slow, controlling memory layout on modern computers can be a big deal, assuring that you hit the L1 and L2 cache as much as possible.
-
There are also just some cultural things, people working on the C and C++ ecosystems are doing so because performance is priority one. People working on ecosystems of memory safe languages obviously have a bit of priority for safety, correctness, or productivity or they wouldn't want the GC!
None of these things in isolation is normally a very big deal but they can add up.
More on reddit.comWhy is golang's performance worse than Java's in this benchmark game?
Yes, it is memory allocator and probably the fact that bottomUpTree() is called a lot, recursively.
That being said, making sweeping statements (like "Go's GC is immature") based on a single benchmark is not exactly right. Both Go and Java have state-of-the art garbage collectors but they are tuned for different scenarios and this benchmark has a workload that heavily favors Java's GC.
Why? Because Java's collector is generational. That means that allocation is extremely cheap (bump of the pointer). The downside is that generational GCs use more memory and when objects are moved from nursery to tenured heap, there's additional work of copying the memory.
Go's GC is not generational, so allocation requires (comparatively speaking) much more work. It's also tuned for low latency (smallest pause when GC has to stop the program) at the expense of throughput (i.e. total speed). This is the right trade-off for most programs but doesn't perform optimally on micro-benchmarks that measure throughtput.
I've made a Go version that allocates nodes in bulk https://gist.github.com/kjk/4620bf60315d3fdd3f210e4590bdf1cb using a pool allocator of nodes.
On my machine it goes from 17s to 9s (if I allocate 1024 nodes at a time) or 7s (if I allocate 32*1024 nodes at a time).
In this particular program the number of nodes could be calculated up-front so it could be sped up even more.
Another thing where Java probably has an advantage is the fact that almost all the time is spent calling bottomUpTree() a lot, recursively.
Why is it worse than in Java?
To make goroutines cheap, Go starts each goroutine with very small stack (~4kb). As a result, Go has to expand the stack when needed. Go does that by checking stack size at the beginning of every function call. When it detects it needs more stack, it creates a new, bigger stack and copies the old stack to new one.
The cost is usually very small (few instructions for each function call) but if there is a function like bottomUpTree() that does little work and is called very often, even small cost adds up.
Additionally, this is deeply recursive call, so stack is being copied several times when it needs to be expanded.
I'm pretty sure that if you rewrote bottomUpTree() to be non-recursive (non-trivial but possible) and used pool allocator for nodes, Go version would be as good (if not better) than Java.
More on reddit.comVideos
Hi all,
First of all, forgive me to ask this. I am a noob to Golang and find it very promising to learn. I read that Golang is not as performant as C or C++ code. What's the reason behind this? AFAIK Golang is very close to C or inherits many features. If this is the case, why is Golang gaining popularity? How about the future of Golang developers? What's the primary domain of use - cloud?
Some people like to blame all of the slowness of languages like Go, C#, and Java on garbage collection, but that isn't a very complete story. People will correctly tell you that normally garbage collection takes up a very very small % of total runtime, and that is true, so what else is going on? There are some indirect and related things as well.
-
Languages that have garbage collection are attempting to be memory safe languages, so:
-
They will also tend to have array bounds checks when the compiler can't prove they can be elided
-
They will tend not to allow as many clever casts
-
They will tend not to allow pointer arithmetic
-
Providing ways to leverage SIMD instructions by hand is hard (Go gives access only through Go assembler at the moment)
-
They will tend not to have a way for the compiler to do floating point optimizations that can change results like --ffast-math in C compilers
-
-
Garbage Collection has some indirect effects aside from how much time is spent doing GC
-
Every time the GC runs it pollutes the CPU caches, slowing down code that runs later
-
GC will normally imply a degree of overhead when doing FFI (interop with other languages). Go has even more overhead due to how it manages it's stack, which facilitates goroutine features. Lots of things require FFI still (3d rendering, for example) so those things will always be slower.
-
The control you get over memory layout of your data is usually limited to some degree. For instance in Go you can't explicitly control whether data goes on the stack, or heap, or *where* to goes on the heap. On the bright side in Go you can at least work with any type you create as a value or a reference, so you can at least control things like making sure your array is an array of values in contiguous memory vs an array of references, which you can't in Java. Accessing RAM is very slow, controlling memory layout on modern computers can be a big deal, assuring that you hit the L1 and L2 cache as much as possible.
-
There are also just some cultural things, people working on the C and C++ ecosystems are doing so because performance is priority one. People working on ecosystems of memory safe languages obviously have a bit of priority for safety, correctness, or productivity or they wouldn't want the GC!
None of these things in isolation is normally a very big deal but they can add up.
There are tons of differences in the implementations of C and Go that slightly slow down Go in favour of safety. A few things:
-
goroutine scheduling
-
growing stacks
-
Runtime checks for memory access (you panic on nil not segfault)
-
runtime reflection
-
Bounds checking on arrays/slices
-
No naive casting (safe type assertion)
-
Different calling conventions
-
this allows panics at any pint
-
Go relies more on the stack (no fastcall)
-
-
Defer
-
Much fewer optimizations in favour of fast compile times
-
latency optimized GC, this limits throughput
All of this and much more lead to the fact that cgo has quite some overhead.
C is still the most dominant language and this will be remain true longer than we all live. Go improves C in lots of aspects that address issues faced today.
-
Go is memory safe making it way less dangerous to program critical systems
-
Great multicore capabilities in times after Moore's law
-
Go scales great
So I have recently watched an interview where Ken Thompson was saying he got convinced to build Go after he read some C++ codebase. I also read some blogs saying the same.
But how can Go compete with C++ which has manual memory management ?
The reason people are using C++ is because of its Speed and ability to manually manage the memory right ?
How can Go which has GC be used to write Game development, HFT softwares, automobile softwares, embedded and expect the same result as that of a manually memory managed language?
Or is there any plan to add manual memory management to Go ? Which would make it really awesome ig ?
Here is the Google I/O conference
Ps: Beginner.
Edit: By competitor I meant the same things C++ does that go does it easier and better.
I think many people thought I was trying to make a language war here lol.
As i specifically mention above I'm a beginner and I was just trying to get the thoughts of experienced devs who used both.