My opinions on Golang vs Rust : which to pick

Performance

Go: Originally designed by Google’s engineers, Go was introduced in 2009 as an alternative to C++. It’s optimized for running on multicore CPUs and is known for its concurrency through Goroutines. The ease of use of Goroutines allows distributing workloads across multiple CPU cores, making it a very efficient language.

Rust: Rust was designed from the ground up to deliver high performance. The way Rust handles memory management means that the language doesn’t require a garbage collector like Go does, allowing objects to be passed without creating copies.

Rust vs. Go Benchmarks

Individual benchmarks can be manipulated and are often tricky to interpret. The Benchmarks Game deals with this issue by allowing multiple programs for each language and comparing how long they take to execute, as well as memory usage and code complexity, to provide a better sense of the trade-offs between languages.

In all the tested algorithms, the most optimized Rust code was at least 30% faster than the most optimized Go code, and in many cases, it was significantly more. For example, in the binary-trees benchmark, the most optimized Rust code was 12 times faster than the most optimized Go code.

Scalability

Both languages excel at scaling up to take advantage of many CPUs to process data in parallel. In Go, you can use a Goroutine to process each piece of data and employ a WaitGroup to wait for them all to finish. In Rust, “rayon” is a very useful library that simplifies iterating over a container in parallel.

Concurrency

As mentioned earlier, Go supports concurrency through Goroutines. For instance, if you’re running a web server that handles API requests, you can use Go’s Goroutines to run each request as a subprocess, maximizing efficiency by offloading tasks to all available CPU cores.

Goroutines are part of Go’s built-in functions, whereas Rust has only recently received native “async/await” syntax to support concurrency. Consequently, in terms of developer experience, Go has an edge when it comes to concurrency. However, Rust excels at guaranteeing memory safety.

Memory Safety

The concept of “ownership” is one of Rust’s main selling points. Rust takes type safety, which is also crucial for enabling memory-safe concurrency, to the next level.

According to the Bitbucket blog, “Rust’s very strict and pedantic compiler checks every variable you use and every memory address you reference. It avoids possible data race conditions and informs you about undefined behavior.”

This means you won’t end up with a buffer overflow or a data race condition due to Rust’s strong emphasis on memory safety. However, this also comes with drawbacks, such as the need to be highly aware of memory allocation principles while writing code.

Developer Experience

Let’s begin with the learning curve associated with each language. Go was designed with simplicity in mind. Developers often refer to it as a “boring” language, implying that its limited set of built-in features makes Go easy to adopt.

Furthermore, Go offers a simpler alternative to C++, abstracting aspects like memory safety and memory allocation. Rust, on the other hand, forces you to consider concepts like memory safety. The concept of “ownership” and the ability to pass pointers make Rust a less appealing option to learn. When you’re constantly focused on memory safety, you’re less productive, and your code tends to be more complex.

The learning curve for Rust is steeper compared to Go. It’s worth mentioning that Go has a steeper learning curve than more dynamic languages like Python and JavaScript.

Development Cycles

For modern software developers, the ability to iterate quickly is crucial, as is the capability to have multiple people working on the same project. Go and Rust achieve these goals in slightly different ways.

The Go language is straightforward to write and understand, making it easy for developers to comprehend each other’s code and extend it. However, in Go code, you must be cautious about error checking and avoiding nil accesses; the compiler doesn’t provide much assistance in this regard.

Rust code is trickier to write and make compile; developers need a good understanding of references and lifetimes, among other things, to be successful. However, the Rust compiler does an excellent job of catching these issues (and emits incredibly helpful error messages – in a recent survey, 90% of Rust developers approved of them!). So while “Once your code compiles, it’s correct!” isn’t true for either language, it’s closer to the truth for Rust, which gives other developers more confidence in working on existing code.

Features

Both languages offer a solid array of features. As seen earlier, Go has built-in support for various useful concurrency mechanisms, primarily Goroutines and channels. The language supports interfaces and, as of Go v1.18, released in March 2022, generics. However, Go doesn’t support inheritance, method or operator overloading, or assertions. Given that Go was developed by Google, it’s no surprise that it has excellent support for HTTP and other web APIs, and there’s also a large ecosystem of Go packages.

The Rust language is a bit richer in features compared to Go. It supports “traits” (a more sophisticated version of interfaces), generics, macros, and rich built-in types for nullable types and errors, as well as the “?” operator for easy error handling. It’s also easier to call C/C++ code from Rust than it is from Go. Rust also boasts a large ecosystem of crates (libraries).

When to Use Go

Go works well for a wide variety of use cases and is an excellent alternative to Node.js for creating web APIs. As noted by Loris Cro, “Go’s concurrency is a good fit for server-side applications that must handle multiple independent requests”. This is precisely why Go provides Goroutines.

Furthermore, Go has built-in support for the HTTP web protocol. You can quickly design a small API using the built-in HTTP support and run it as a microservice. Therefore, Go fits well with the microservices architecture and serves the needs of API developers.

In short, Go is a good fit if you value development speed and prefer syntax simplicity over performance. Additionally, Go offers better code readability, which is an important criterion for large development teams.

Choose Go when:

  • You care about simplicity and code readability.
  • You want an easy syntax to quickly write code.
  • You want to use a more flexible language that supports web development.

When to Use Rust

Rust is an excellent choice when performance is critical, such as when processing large amounts of data. Furthermore, Rust gives you fine-grained control over how threads behave and how resources are shared between threads.

On the other hand, Rust comes with a steep learning curve and can slow down development speed due to the added complexity of memory safety. However, this is not necessarily a disadvantage; Rust also guarantees that you won’t encounter memory safety bugs, as the compiler checks every data pointer. For complex systems, this assurance can be invaluable.

Choose Rust when:

  • You care about performance.
  • You want fine-grained control over threads.
  • You prioritize memory safety over simplicity.

Go vs. Rust: My Honest Take

Let’s start by highlighting the similarities. Both Go and Rust are open-source and designed to support the microservices architecture and parallel computing environments. Both optimize the utilization of available CPU cores through concurrency.

But at the end of the day, which language is best? There are many ways to approach this question. I would recommend thinking about the type of application you want to build.

Go works well for creating web applications and APIs that take advantage of its built-in concurrency features while supporting the microservices architecture.

You can also use Rust to develop a web API, but it wasn’t designed with this use case in mind. Rust’s focus on memory safety increases complexity and development time, especially for a fairly simple web API. However, the greater amount of control you have over your code allows you to write more optimized, memory-efficient, and performant code.

To put it as simply as possible, the Go versus Rust debate is really a question of simplicity versus security. Both languages are powerful, but they excel in different ways based on your specific needs.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *