From Node to Go: A High-Level Comparison
At XO Group, we primarily work with Node and Ruby to build out our system of interconnected services. We get the implicit performance benefits of Node mixed with the access to a large, established repository of packages. We also have the ability to easily break out plugins and modules that can be published and reused across the company. This greatly increases developer efficiency and allows us to make scalable and reliable applications in a short amount of time. Furthermore, the large Node community makes it easy for our engineers to contribute open source software (see BunnyBus or Felicity).
Although a good portion of my college days and early career was spent using strict compiled languages, like C++ and C#, I eventually shifted to using Javascript. While I love the freedom and flexibility, I recently found myself nostalgic for static and structured languages. That’s when a coworker turned my attention to Go.
Coming from Javascript, there are some similarities between the two languages. Both are very fast, fairly easy to learn, have an expressive syntax, and a niche in the development community. There isn’t a perfect programming language and you should always choose a language that fits the project at hand; In this post, I will attempt to illustrate some of the key differences between the two languages at a high level and hopefully encourage anyone new to Go to give it a ̶g̶o̶ chance.
General Differences
Before we dive into specifics, we should understand some important distinctions between the two languages.
Go, or Golang, is a free, open-source programming language created by Google in 2007. It was designed to be fast and simple. Go is compiled down into machine code, which is where its speed is derived from. Debugging is fairly easy with a compiled language because you are able to catch a large chunk of errors early on. It is also a strongly typed language which helps with data integrity and finding type errors at compile time.
Javascript, on the other hand, is a loosely-typed language. Aside from the added burden of data validation and “truthy” evaluation pitfalls, using a loosely-typed language can can have its own benefits. There is no need for interfaces or generics and currying/flexible arity make functions extremely versatile. Javascript is interpreted at runtime, which can lead to issues with error handling and debugging. Node is a Javascript runtime built on Google’s V8 virtual machine making it a lightweight and fast platform for web development.
Syntax
Coming from Javascript, Go’s simple and intuitive syntax was very inviting. Since both languages’ syntaxes are said to have evolved from C, there is quite a bit of overlap. Go is commonly referred to as an ‘easy language to learn.’ This is due to the developer-friendly tools, pared-down syntax, and opinionated conventions.
Go has a number of built-in features that make development a bit easier. The standard Go build tool lets you compile your code down into a binary file or executable with the go build command. Running tests with the built-in test suite are as simple as calling go test. Things like natively-supported concurrency are even available at the language level.
According to the Go developers at Google, programming today is too complicated with too much “book keeping, repetition, and clerical work.” This is why the Go’s syntax was designed to be clean and simple in order to reduce clutter, increase efficiency, and improve readability. It also encourages developers to write explicit, easy to understand code. As a result, Go only has 25 unique keywords and one type of loop (for-loop) as opposed to ~84 keywords (reserved words, objects, properties, and methods) in Javascript.
In order to illustrate some syntactical differences and similarities, let’s look at a couple of examples:
- Punctuation: Go strips out any superfluous punctuation in order to increase efficiency and readability. Although Javascript’s use of punctuation is somewhat minimal (see: Lisp) and often optional, I definitely enjoy the simplicity with Go.
- Assignment: Since Go is strongly typed, you have access type inference on initialization with the := operator to reduce stuttering, whereas Javascript declares types on runtime.
- Exporting: In Javascript, you must explicitly export from a module. In Go, any capitalized functions will be exported.
- Importing: The required library is necessary for importing dependencies/modules in Javascript, whereas Go utilizes the native import keyword with the import path to the package. Another distinction is that, unlike Node’s central NPM repository for packages, Go uses URLs for the import path on non-standard libraries in order to directly clone dependencies from their origin. Although this provides a simple and intuitive dependency management, versioning packages can be a bit more tedious in Go as opposed to updating the package.json file in Node.
- Returns: Go’s multiple value returns allow for elegantly passing and handling values and errors, as well as reducing the improper passing of values by reference. In Javascript, multiple values must be returned by an array or object.
- Errors: Go encourages catching errors often and where they occur as opposed to bubbling the error up in a callback in Node.
- Variadic Functions: Both Go and Javascript support functions that accept a fluid number of arguments.
Communities
Although Go and Node have their differences when it comes to which programming paradigms they enable to be easier, they both have unique and supportive followings. One area where Node outshines Go is in the sheer size of their package library and community. Node package manager (NPM), the largest package registry in the world, has over 410,000 packages growing at an alarming rate of 555 new packages per day. That number may seem staggering (and it is), however, something to keep in mind is that many of these packages are redundant and/or non-production quality. In contrast, Go has about 130,000 packages.
Although Node and Go are around the same age, Javascript is more widely used — boasting a large development and open-source community. This is of course because Node was developed for the general public with a robust package manager from the start while Go was specifically built for Google. The Spectrum ratings below show the top web development languages based on current trends.
While Javascript’s popularity seems to have stayed relatively static over recent years, Go has been trending up.
Performance
What if your primary concern is speed? In this day and age, it seems performance optimizations are more important than ever. People don’t like to wait for information. In fact, 40% of users will abandon your site if it takes longer than 3 seconds to load.
Node is often touted as a highly performant because of its non-blocking asynchronous I/O. Also, as I mentioned before, Node is run on Google’s V8 engine which was optimized for dynamic languages. Go on the other hand was designed with speed in mind. The developers at Google achieved this by building “an expressive but lightweight type system; concurrency and garbage collection; rigid dependency specification; and so on.”
To compare the performance of Node and Go, I ran a couple of tests. These focus on the rudimentary, low-level abilities of the languages. If I had been testing something like HTTP requests or time-intensive processes, I would have used Go’s language-level concurrency tools (goroutines/channels). Instead, I stuck to basic features of each language (see Concurrency in Three Flavors for a deeper look into goroutines and channels).
I also included Python in the benchmarks so we feel good about the Node and Go results no matter what.
Loop/Arithmetic
Iterating through a billion items and adding them up:
The clear loser here is Python clocking in at over 7 seconds. On the other hand, both Node and Go were extremely efficient, clocking in at 900 ms and 408 ms, respectively.
Edit: As some of the comments suggest, Python’s performance could be improved. The results have been updated to reflect those changes. Also, the use of PyPy greatly improves the performance. When run using Python 3.6.1 and PyPy 3.5.7, the performance improves to 1.234 seconds, but still falls short of Go and Node.
I/O
Iterating over 1 million numbers and writing them to a file:
Once again, Python is third at 7.82 seconds. The gap between Node and Go is quite large in this test with Node taking about 1.172 seconds and Go taking 213 ms. What is really impressive though is that the majority of Go’s processing time is spent compiling. If we compile the code via go run down into a binary, the I/O task only takes 78 ms — more than 15 times faster than Node.
Edit: Changed Go code to implement buffered I/O.
Bubble Sort
Iterating 1 million times over a 10-item array and sorting:
As usual, Python’s performance was the poorest, completing the task at hand in about 15 seconds. Go was able to finish the task over sixteen times faster than Node.
Verdict
Go is the clear winner in all three tests, but Node, for the most part, performs admirably. And Python was there, too. To be clear, performance isn’t everything when choosing a programming language. If your application doesn’t need to process high amounts data, then the differences in performance between Node and Go may be negligible. For some additional comparisons on performance, see the following:
Conclusion
This post is not to prove that one language is better than another. Every programming language has its place in the software development community for one reason or another. My intentions were to highlight the differences between Go and Node, as well as promote exposure to a new web development language. When choosing a language for a given project, there are a lot of different factors to consider including developer familiarity, cost, and practicality. I encourage a thorough low-level analysis when deciding what language is right for you.
As we have seen, there are several benefits to Go. The raw performance, simple syntax, and relatively shallow learning curve make it ideal for scalable and secure web applications. With its fast growth in adoption and community involvement, there is no reason Go can’t become a prominent player in modern web development. That being said, I believe that Node is moving in the right direction to remain a powerful and useful language if implemented correctly. It has a large following and active community that makes it a simple platform for getting a web application up and running in no time.
Resources
If you are interested in learning more about Go, consider the following resources:
About the Author
John Stamatakos
John Stamatakos is a Software Engineering Manager at XO Group in Austin, Texas. He enjoys learning new programming languages, teaching at bootcamps, hanging out with his wife and dogs, supporting the local taco economy, and writing in the third person.