Is Go a viable alternative now?
Is Go a viable alternative now?
The thing that may replace C and C++ right in the niches that are keeping those now-ancient languages current is probably Rust. If successful, Rust will grow beyond that, but it's the only thing squarely pointed at C and C++ right now that seems to have the momentum behind it. Though if you want something right now, you can also try D.
*GC is a non-starter. An HD frame buffer is around 3MB, a 4K buffer is around 13MB. Letting a GC manage your buffers will lead to heap fragmentation and bring down 32-bit builds relatively quickly.
*Similarly you don't want to copy these things unless you have to so a strategy where each filter is responsible for its own buffers will result in roughly a 3x factor in memory bandwidth.
*All of the downstream software is written in C. So just to get it into GO I either need to do another memcpy or use unsafe stuff in order to deal with it nativly in Go. This along with the above means that I would be looking at 2GB/s of memory bandwidth per stream instead of 500MB/s for a 4K stream.
*My upstream targets include software written in Python and C#. Go appears to assume that it owns main, which is obviously a problem.I like Go, but I don't really consider myself an "advocate", and part of that is not overpromising to people. If you've got really heavy-duty computational needs, like in science or graphics, it's a bad choice right now, and I expect it to remain so for the forseeable future because it's not a core concern of the devs, and I'm pretty sure they'd view it as dilution of their goals and value proposition. (Correctly, I might add.)
1. Embedded, real-time, kernel: As a GC language which is not meant to write close-to-the-metal code and produces rather bloated binaries (especially compared to C), Go has no chance here. This trinity is still very much the sole territory of C where even C++ seldom dares to tread.
2. Truly cross-platform (not just Windows/Linux/Mac) performance-sensitive libraries that need to be callable (using bindings) from a wide range of programming languages (including C). This is a very common but often neglected class of software where C/C++ reign supreme. Libraries need lots of flexibility in terms of ABI support (e.g. support linking with different C stdlibs) and deployment (e.g. dynamic libraries, which Go, AFAIK, still doesn't support).
3. Complex and lightweight GUI apps with high performance: This is the main class of application mentioned in the blog post. While there are some Go bindings to popular GUI libraries such as Qt and GTK, I'm not sure if their mature enough. Using Qt directly from C++ still seems like the path of least resistance to me. As for lightweight apps, Go apparently still has some work to do about the binary sizes.
4. Web Servers: This is where Go should shine! Programming a concurrent web server using Goroutines should be a breeze, and considering most web servers are still written in C, we would be relieved of the nightmare that is string manipulation in C. But right now, there's still doesn't seem to be any Go equivalent of nginx in development. Go is probably getting mature enough, but I think that if actually squeezing every last ounce of performance is your goal, it still can't beat nginx. For instance, nginx employs many tricks to optimize its memory allocation pattern specifically for the task it was meant to do, and I find it hard to believe that any one size fits all GC, no matter how intelligent, can get the same performance.
There's no nginx in development because the built-in net/http library is actually pretty close to it already. Nginx beats it, but only by something like 25-50%, and if you compare the nginx source code to the net/http source code you'll see why nginx is going to likely retain that lead and Go isn't interested in the code quality tradeoff it would take to catch up to nginx. If you ever need an example of C used as "portable assembler", cite the core loop code of nginx.
That is one of the primary domains of C++ - e.g. photoshop and similar tools.
Go seemed more oriented towards server programming.
Reasons why C and C++ are the only options might include:
- small executable size. Hello world in Go is over a megabyte
- real-time without GC pauses
- first class native bindings to a certain third party library
That being said, Go is certainly taking market share from applications that traditionally would be written in C/C++. Take Docker, for example. It theoretically could be written in any language that can do networking and Linux syscalls, but pre-golang C or C++ probably would have been the best choice.
I personally see Go as more of a Java killer than a C++ alternative.
Its also worth mentioning using a custom allocator + mmap is possible in Go if you really needed it.
Go is also better than Java about using stack allocation for objects.
Barring major implementation mistakes this should be self-evident, but you could easily write some benchmarks to verify. Its worth noting that if the Java GC was good enough people would not bother to write object pools in Java- but they do. And Go has a very advanced GC/mutliprocessor aware object pool implementation built in its stdlib.
In an typical object pool only allocation up to the peak concurrent demand for the given object type will ever be allocated and the kicker is that allocation will only happen once. Adding thread-local caching means that that will scale well on multiprocessor systems.
TL;DR: A system that does not generate garbage is going to be faster than a system that does. My argument is that effective use of a good object pool implementation in Go is faster than even a more advanced garbage collector would be.
Modern C++ compilers do auto-vectorization, offer OpenMP, etc. Of course, you can work around this by writing your numerical code in C or C++, let your C/C++ compiler do the work and bind from cgo.
Another shortcoming of Go is that it cannot be used for building non-Go libraries. First of all because the defacto compiler cannot create shared libraries, secondly, because having a garbage collector gives ownership difficulties once you start binding against another language with a garbage collector.
I will not repeat the usual generics stuff, except that lots of optimizations in C++ code rely on generics (e.g. algorithm selection based on the data type or data type properties).
(No, I am not starting Go bashing season ;), I like Go a lot and it can be used to replace C++ in many projects. Just stating the weak points when coming from C++.)