Comparison and Analysis of Go and Rust

Rust and Go are two modern languages ​​that have gained enormous traction in recent years, each with its own unique strengths and tradeoffs. In this post, we'll dive into the differences between Rust and Go, focusing on performance, language features, and other key factors to help you make an informed decision for your development needs.

In 2023, we have a thousand reasons to learn Rust.

On August 7, the Rust Foundation released the results of the 2022 Rust Survey Report. Reports show that Rust adoption continues to increase. Over 90% of respondents said they were Rust users; Rust is used for the majority of coding work, a massive 51.8% increase from the previous year.

There is no doubt that Rust has increasingly become the focus of developers' attention due to its excellent memory safety and concurrency performance. However, it's also hard to ignore Go, a relatively "veteran" player who was once selected as the programming language of the year.

Born in 2009, the Go language has received great attention from the very beginning because of its unique concurrency model and powerful performance advantages. It is worth noting that, like the Rust language, the creators of the Go language also "hate" C++, and Go is also the dominant language of cloud native.

In the Stack Overflow 2022 developer survey, among the 70,000 responses to the question "A programming language that people love to hate", programmers clearly prefer Rust, with 86% saying they like Rust, 64% of people say they like Go. Faced with the popularity of Rust, some developers ask themselves: Is Go still worth learning in 2023?

In addition, in the past two days, whether to choose Rust or Go has become a hot topic on Hacker News:

I have to say that both Go and Rust are definitely excellent programming languages. They are modern, powerful, versatile and offer great performance. But it really doesn't make sense to directly compare Go and Rust, which is better, because each programming language represents a series of deep tradeoffs behind it. Different languages ​​will be optimized for different needs, so when we choose a language, we should also consider what kind of problems we want to use it to solve. Therefore, we will start from the applicable scenarios of Go and Rust languages, and discuss the "way" of Go and Rust's design.

While Rust and Go differ greatly in syntax and style, both are first-class tools for building software. Let's start the specific analysis below.

Go vs. Rust: The Similarities

Rust and Go have a lot in common, which is why people often compare the two. What goals do they have in common?

Rust is a low-level statically typed multi-paradigm programming language with a greater focus on safety and performance.

and:

Go is an open source programming language that makes it easy to build simple, reliable, and efficient software.

memory safety

Both Go and Rust are modern programming languages ​​that take memory safety very seriously. Over the decades of old languages ​​like C and C++, it has become clear to us that one of the core causes of bugs and bugs is unsafe/incorrect access to memory.

Therefore, Rust and Go each give different solutions, but the goal of both is to be smarter and safer in terms of memory management, and to help developers write correct programs with excellent performance.

Fast, compact executable

Both are compiled languages, which means that programs can be translated directly into executable machine code, allowing programs to be deployed as a single binary file. Unlike interpreted languages ​​like Python and Ruby, we don't need an interpreter and lots of libraries/dependencies to ship with our programs. As a direct reflection of this core strength, Rust and Go programs tend to run faster than interpreted languages.

common language

Both Rust and Go are powerful and extensible general-purpose programming languages ​​that can be used to develop all kinds of modern software—from web applications to distributed microservices to embedded microcontrollers and mobile applications, and more.

Both have excellent standard libraries and thriving third-party ecosystems, coupled with strong commercial support and large user bases. Both have been around for years and will continue to thrive in the years to come. Learning Go or Rust would be a very reasonable investment of time and effort these days.

pragmatic programming style

They are neither overly functional (such as Scala or Elixir) nor fully object-oriented (such as Java and C#). On the contrary, although both Go and Rust have functional and object-oriented programming functions, they always emphasize a pragmatic orientation-that is, to solve problems in the most appropriate way, rather than forcing everyone to follow a specific way through "ideology". work. ".

But if you really like the functional programming style, there are more relevant tooling options on the Rust side, which is one of Rust's advantages over Go.

We can certainly argue about what constitutes a true "object-oriented" language. But to be fair, the object-oriented programming style that users of C++, Java, or C# expect doesn't really exist in Go or Rust.

large-scale development

Both Rust and Go provide many useful features for large-scale programming, so they can both adapt to the practical needs of large development teams and large code bases.

For example, C programmers have debated for years about how to place parentheses, and whether code should be indented with tabs or spaces; but Rust and Go have completely resolved these using standard formatting tools (Go has gofmt, Rust has rustfmt) question. They automatically rewrite your code with a consistent style.

Not that this particular format is subtle, but Rust and Go programmers are more pragmatic and prefer a uniform implementation standard.

gofmt's style no one likes, but gofmt is everyone's favorite.

Another big advantage of both languages ​​is in building pipelines. Both have excellent, built-in, high-performance standard build and dependency management tools. This means programmers don't have to contend with complicated third-party build systems, or learn a new one every few years.

Rust or Go?

Having said all these questions, and both languages ​​are so well designed and functional, what is the outcome of this competition? Or, since both are great options, why are people still outraged on social media, writing long review blog posts saying harsh things like "Rust is an idiot" or "Go isn't a programming language at all"?

Of course, some people just want to vent their emotions, but this obviously does not help to solve the actual problem. At least when it comes to which language to use in a project, or which language to break into the world of programming, loud voices are clearly not helpful in making the right choice.

Let's go back to the adults' discussion and see what are the advantages and disadvantages of Rust and Go under rational analysis.

Go vs. Rust: Performance

As mentioned earlier, both Go and Rust generate programs that are fast because they compile to native machine code without going through an interpreter or a virtual machine.

But Rust's performance is still better, even comparable to C and C++, which are hailed as industry performance benchmarks. And unlike these older languages, Rust also offers memory safety and concurrency safety with little to no impact on execution speed. Rust also allows developers to build complex abstractions without a performance penalty at runtime.

In contrast, while Go programs perform well, they are designed with a focus on development speed (including compilation) rather than execution. Go programmers prefer clean and readable code, so it will run slower.

The Go compiler also doesn't spend much time generating the most efficient machine code, it's more concerned with compiling large amounts of code quickly. As a result, Rust programs often beat Go programs in runtime benchmarks.

Rust's runtime performance is also very consistent and predictable because it doesn't use garbage collection. Go's garbage collector is very efficient and is optimized to keep pause times as short as possible (the pause times get shorter with each new version of Go). But anyway, garbage collection will always introduce some unpredictability in the way the program behaves, which can be serious or even completely unacceptable for some applications (e.g. embedded systems).

Simple

It doesn't matter how powerful a programming language is if it's too hard to learn and turns most people off. Go seems to have been deliberately designed to differentiate it from increasingly complex languages ​​like C++: it has very little syntax, very few keywords, and even few functions.

This means that the Go language is easy to learn, and you can use it to write all kinds of programs with a little understanding.

The key here is the word "simple". Of course, simple doesn't mean easy. But small and simple languages ​​are definitely easier to learn than large and complex ones. There aren't many ways to achieve one effect, so high-quality Go code almost always looks the same. This has another benefit: we can quickly see what services we're not familiar with are doing.

Go's core ontology is small, but the standard library is very powerful. That said, our learning curve had to account for this part of the standard library in addition to the Go syntax.

On the other hand, moving functionality from the language to the standard library means that you only need to focus on learning the libraries relevant to your current development needs.

Go is also designed to fully consider the needs of large-scale software development, and can strongly support large code bases and development teams. In this scenario, new developers must be able to pick up quickly. To this end, the Go community has always prioritized simplicity, clarity, versatility, and directness of programs.

Go is one of the most productive languages ​​I've ever used. The mantra is: Solve real problems today.

Function

Rust supports more complexity than several other programming languages, and thus a correspondingly larger range of implementations.

Rust has been specifically designed to include a variety of powerful and useful features that help programmers do more with less code. For example, Rust's match function makes it possible to quickly write flexible and expressive logic:

But also because Rust has more design considerations, it is more difficult to learn, especially in the initial stage. But that's okay, C++ or Java is a lot to learn after all, and it doesn't even offer Rust's advanced features like memory safety.

So it really doesn't make sense to criticize Rust's overly complex sound: it's designed to emphasize expressiveness and rich functionality, and we can't expect it to be so simple and pure while enjoying the benefits.

So Rust of course has its own learning curve. But as long as this difficulty is overcome, the road ahead will be smooth.

Rust competes with C++ and D for the mind share of programmers who are ready to accept more complex syntax and semantics (and possibly a higher readability cost) in exchange for the greatest possible performance.

While Rust and Go borrow some features from each other (such as generics), it's fair to say that Rust's features are better than Go's.

concurrency

Most languages ​​provide some form of concurrent programming support (i.e. executing multiple operations at the same time), but Go is designed for this. Instead of using operating system threads, Go provides a lightweight alternative: goroutines.

Each goroutine is an independently executing Go function that the Go scheduler maps to one of the operating system threads under control. That is, the scheduler can manage large numbers of concurrent goroutines very efficiently while using only a limited number of operating system threads.

Thus, we can run millions of concurrent goroutines in a single program without worrying about serious performance issues. Because of this, Go is a complete solution for large-scale concurrent application scenarios such as web servers and microservices.

Go also provides channels for goroutines, a fast, safe, and efficient way to communicate and share data. Go's concurrency design level is indeed very high, and the use experience is quite relaxed and pleasant.

In general, the design of concurrent programs is very difficult, and building reliable and correct concurrent programs in any language is by no means easy. However, since this requirement was considered at the beginning of the project, the concurrent programming mechanism in Go has been made as simple as possible and well integrated.

Go makes it very easy to build a carefully decomposed application that takes full advantage of concurrency when deployed as a set of microservices.

Rust can do these things too, but it's arguably harder. In some ways, Rust's obsession with preventing memory-related security holes means that programmers must go to great lengths to perform tasks that are easier in other languages ​​(including Go)

In contrast, the concurrency mechanism in Rust has just landed and has not yet stabilized, so everyone is welcome to continue to pay attention to this active development direction. This is also beneficial. For example, Rust's rayon library provides a very elegant and lightweight way to convert sequential computations to parallel ones.

While it may not be easy to implement concurrent programs in Rust, it's still perfectly doable, and these programs also benefit from Rust's well-designed memory safety guarantees.

Take the standard library's Mutex class, for example: in Go, we might forget to acquire a mutex before accessing something; but in Rust, we don't have to worry about it at all.

Go has concurrency as its first concept. That's not to say you can't find aspects of Go's actor-oriented concurrency in Rust, but leave it as an exercise for the programmer.

Safety

As mentioned earlier, both Go and Rust have their own ways of preventing various common programming mistakes, especially those related to memory management. But Rust goes one step further, and it can be said that it spares no effort to ensure that everyone does not make unexpected security mistakes.

That said, the programming experience in Rust is different from almost any other language, and can be quite challenging when first introduced. But in the eyes of many developers, the effort is clearly worth it.

Many languages, including Go, also provide tools to help programmers avoid mistakes, but Rust takes this effect to a new level. Many incorrect programs don't even compile at all.

Rust vs. Go: Differences

While both Rust and Go are popular and widely used modern languages, they are not really competitors as they address very different use cases.

The whole approach to programming in Go is quite different from Rust, features that are particularly appealing to some but can completely irritate others. This makes sense, because if Rust and Go both solve essentially the same problems in essentially similar ways, why do we need two different languages?

So, can we start with the practices of Rust and Go and interpret their respective essences? Let's try it together.

garbage collection

"To garbage collect, or not to garbage collect" is always a question that doesn't have a right answer. Collectively, garbage collection and automatic memory management can help us develop reliable, efficient programs quickly and easily. So for some developers, these are essential features.

Others argue that garbage collection with its performance overhead and global pauses can lead to unpredictable runtime behavior and introduce unacceptable latency. Of course, there is some truth to this claim.

close to hardware

The history of computer programming can be described as a development of increasingly complex abstractions. It allows programmers to solve problems without paying too much attention to how the underlying hardware actually operates.

This design makes programs easier to write and more portable. But for other programs, access to hardware and precise control over how the program executes is more important.

Rust's goal is to bring programmers "closer to the hardware" and regain more control; while Go abstracts architectural details and allows programmers to be closer to problems.

Golang is good at writing microservices and typical "DevOps" tasks, but it's not a systems programming language. Rust is more powerful for tasks where concurrency, safety, and/or performance are important; but it has a steeper learning curve than Go.

performance first

In fact, for most programs, performance is not as important as code readability. However, if some projects do put performance first, there are many design trade-offs in Rust that will help you push your code all the way to the limit.

In contrast, Go cares more about code simplicity and is even willing to sacrifice some runtime performance for it. But Go's build speed is unmatched, which is often even more important for large code projects.

Rust performs faster than Go. In benchmarks, Rust is indeed faster, in some cases by an order of magnitude. But before picking Rust, let's be clear: Go isn't far behind in most benchmarks, and it still maintains a performance advantage over languages ​​like Java, C#, JavaScript, and Python.

Choose either of these two languages ​​if you need top-notch performance, the speed performance will never disappoint. Also, if you're building a web service that handles heavy loads and needs flexible vertical/horizontal scaling, both languages ​​will do the trick.

correctness

On the other hand, if you don't force the program to never fail, the tradeoffs are different. Most code is not designed for long-term use, but some programs do run in production for years.

Faced with these realities, it might be worth investing a little extra time in development and making sure the program works correctly and reliably without creating a heavy maintenance burden down the road.

Both Go and Rust help you write correct programs, but in different ways: Go provides an excellent built-in testing framework, while Rust focuses on eliminating runtime errors through borrow checkers.

For the code to be released tomorrow, use Go; if it is code that must remain stable for the next five years, choose Rust.

While both Go and Rust are good enough for serious development projects, it's best to fully understand their various features and advantages.

In short, it doesn't matter what other people think: only you can decide which programming language is better for your team and project needs.

Summarize

Hope this article helped you understand the highlights of Rust and Go respectively. If possible, you'd better experience both languages ​​a bit, as they are very useful on any technical path, even for amateur programming enthusiasts.

But if you only have time to seriously learn a language, be sure to figure out the respective strengths and tendencies of Go and Rust before making a choice.

Of course, programming language knowledge is only a small part of being a successful software engineer. In addition to programming, engineers must be proficient in design, engineering, architecture, communication, and collaboration. As long as everyone can do the following things well, no matter which programming language you choose, you will become a good software engineering master.

おすすめ

転載: blog.csdn.net/qq_41929396/article/details/132424005