Go is an open source programming language that makes it easy to build simple, reliable, and efficient software. Go is expressive, concise, clean, and efficient. Its concurrency mechanisms make it easy to write programs that get the most out of multicore and networked machines, while its novel type system enables flexible and modular program construction. Go compiles quickly to machine code yet has the convenience of garbage collection and the power of run-time reflection. It's a fast, statically typed, compiled language that feels like a dynamically typed, interpreted language.
In the past couple of years, there is a rise of new programming language: Go or GoLang. Nothing makes a developer crazy than a new programming language, right? So, we started working on Go 4 to 5 months ago and here we are telling you about why you should also use this new language as part of your stack. We are not going to teach you, how you can write “Hello World!!” in this article. There are lots of other articles online for that. We are going to explain why we needed a new language like Go. Even though there wasn’t really a problem that couldn’t be solved by other stacks.
The first Pentium 4 processor with 3.0GHz clock speed was introduced back in 2004 by Intel. Today, a Macbook Pro 2016 has clock speed of 2.9GHz. So, nearly in one decade, there is not too much gain in the raw processing power. You can see the comparison of increasing the processing power with the time in below chart.
From the above chart you can see that the single-thread performance and the frequency of the processor remained steady for almost a decade. If you are thinking that adding more transistor is the solution, then you are wrong.This is because at smaller scale some quantum properties starts to emerge (like tunneling) and because it actually costs more to put more transistors (why?) and the number of transistors you can add per dollar starts to fall.
So, for the solution of the above problem,
- Manufacturers started adding more and more cores to the processor. Nowadays we have quad-core and octa-core CPUs available.
- We also introduced hyper-threading.
- Added more cache to the processor to increase the performance.
But the above solutions have their own limitations too. We cannot add more and more cache to the processor to increase performance as cache have physical limits: the bigger the cache, the slower it gets. Adding more cores to the processor has its cost too. Also, that cannot scale to indefinitely. These multi-core processors can run multiple threads simultaneously and that brings concurrency to the picture. We’ll discuss these later.
That means that if we cannot rely on the hardware improvements, the only way to go is more efficient software to increase the performance. But sadly, modern programming languages are not much more efficient.
“Modern processors are like nitro fueled funny cars, they excel at the quarter mile. Unfortunately, modern programming languages are like the Monte Carlo, they are full of twists and turns.” — David Ungar
Go has goroutines !!
As we discussed before, hardware manufacturers are adding more and more cores to the processors to increase the performance. All the data centers are running on those processors and we should expect an increase in the number of cores in upcoming years. More to that, today’s applications using multiple microservices for maintaining database connections, message queues and maintain caches. So, the software we develop and the programming languages should support concurrency easily and they should be scalable with increased number of cores.
But, most of the modern programming languages (like Java, Python etc.) are from the ’90s single threaded environment. Most of those programming languages support multi-threading. But the real problem comes with concurrent execution, threading-locking, race conditions and deadlocks. Those aspects make it hard to create a multi-threading application on those languages.
For an example, creating a new thread in Java is not memory efficient. As every thread consumes approx 1MB of the memory heap size and eventually if you start spinning thousands of threads, they will put tremendous pressure on the heap and will cause shut down due to out of memory. Also, if you want to communicate between two or more threads, it’s very difficult.
On the other hand, Go was released in 2009 when multi-core processors were already available. That’s why Go is built with keeping concurrency in mind. Go has goroutines instead of threads. They consume almost 2KB memory from the heap. So, you can spin millions of goroutines at any time.
Read a related article that describes how goroutines work: “How do Goroutines work?
- Goroutines have growable segmented stacks. That means they will use more memory only when needed.
- Goroutines have a faster startup time than threads.
- Goroutines come with built-in primitives to communicate safely between themselves (channels).
- Goroutines allow you to avoid having to resort to mutex locking when sharing data structures.
- Also, goroutines and OS threads do not have 1:1 mapping. A single goroutine can run on multiple threads. Goroutines are multiplexed into small number of OS threads.
Watch Rob Pike’s excellent talk: “Concurrency is not parallelism” to get a deeper understanding about this subject
All the points mentioned above, make Go a very powerful to handle concurrency like Java, C and C++ while keeping concurrency execution code strait and beautiful like Erlang. Go takes the best of both worlds. Easy to write concurrent and efficient to manage concurrency.
Go runs directly on underlying hardware.
One of the most considerable benefits of using C, C++ over other modern higher level languages like Java/Python is their performance. Because C/C++ are compiled and not interpreted.
Processors understand binaries. Generally, when you build an application using Java or other JVM-based languages when you compile your project, it compiles the human readable code to byte-code which can be understood by JVM or other virtual machines that run on top of underlying OS. While execution, VM interprets those bytecodes and convert them to the binaries that processors can understand. See below: The execution steps for VM based languages.
While on the other side, C/C++ does not execute on VMs and that removes one step from the execution cycle and increases the performance. It directly compiles the human readable code to binaries.
Freeing and allocating variables in those languages is a huge pain. While most of the programming languages handle object allocation and removing using Garbage Collector or Reference Counting algorithms. Go brings the best of both worlds. Like lower level languages (C/C++), Go is a compiled language. That means performance is almost nearer to lower level languages. It also uses garbage collection to allocation and removal of the object. So, no more malloc() and free() statements.
Code written in Go is easy to maintain.
Go does not have crazy programming syntax like other languages have. It has very neat and clean syntax. The designers of the Go at Google had this thing in mind when they were creating the language. As google has a very large code-base and thousands of developers that were working on that same code-base, code should be simple to understand for other developers and one segment of code should have minimal side effects on other segments of the code. That will make code easily maintainable and easy to modify.
Go intentionally leaves out many features of modern OOP languages.
- No classes. Everything is divided into packages only. Go has only structs instead of classes.
- Does not support inheritance. That will make the code easy to modify. In other languages like Java/Python, if the class ABC inherits class XYZ and you make some changes in class XYZ, then that may produce some side effects in other classes that inherit XYZ. By removing inheritance, Go makes it easy to understand the code also (as there is no superclass to look at while looking at a piece of code).
- No constructors.
- No annotations.
- No generics.
- No exceptions.
The changes mentioned above make Go very different from other languages and it makes programming in Go different as well. You may not like some points from above. But, it is not like you cannot code your application without the above features. All you have to do is write 2–3 more lines. On the positive side, it will make your code cleaner and provide more clarity to your code. See below: Code readability vs, Efficiency.
The graph mentioned above displays that Go is almost as efficient as C/C++, while keeping the code syntax simple as Ruby, Python and other languages. That is a win-win situation for both humans and processors! The syntax of Go is very stable. It remained the same since the initial public release 1.0, back in the year 2012 which makes it backward compatible.
Go is backed by Google
- We know this is not a direct technical advantage. However, Go is designed and supported by Google. Google has one of the largest cloud infrastructures in the world and it is scaled massively. Go is designed by Google to solve their problems of supporting scalability and effectiveness. Those are the same issues you will face while creating your own servers.
- More to that Go is also used by some big companies like Adobe, BBC, IBM, Intel and even Medium. (Source:https://github.com/golang/go/wiki/GoUsers)
- Even though Go is very different from other object-oriented languages, it is still the same beast. Go provides you high performance like C/C++, super efficient concurrency handling like Java and fun to code like Python/Perl.
- If you don’t have any plans to us Go at this moment, We will still say that hardware limits puts pressure software engineers to write super efficient code. Engineers need to understand the hardware and optimize their product accordingly. Optimized products can run on cheaper and slower hardware (like IOT devices) and overall improve the user experience.
Would you like to know if Go is the best solution for your project? See what East Agile can do for you and do not hesitate to Contact us for more information.