this post was submitted on 28 Mar 2024
246 points (94.2% liked)
Rust
5980 readers
114 users here now
Welcome to the Rust community! This is a place to discuss about the Rust programming language.
Wormhole
Credits
- The icon is a modified version of the official rust logo (changing the colors to a gradient and black background)
founded 1 year ago
MODERATORS
you are viewing a single comment's thread
view the rest of the comments
view the rest of the comments
I think focusing on speed of programs is looking at the wrong thing. It's true that at the moment Rust programs are usually faster than equivalent Go programs, but it's already possible to very carefully tune a Go program to achieve similar levels of speed. The real difference is in productivity.
Go makes the tradeoff that it's much more verbose, it takes many times the lines of code to achieve in Go what's possible in either Rust or C++. This is because of their dogmatic obsession with keeping the language "simple". Yes that makes it easy to learn, but it means if you have something complex to express you need to use more of those simple building blocks to do so rather than just a handful of the more complicated ones you're provided in Rust or C++. More lines of code is more opportunity for mistakes to be made and more code to maintain. In a more powerful language you can offload much of the work to libraries that are maintained by other people and that expose powerful APIs that are safe to use. In Go because it's "simple" it's hard to write powerful APIs that aren't filled with footguns and are more complicated to use.
The problem with C++ wasn't that it was a complicated language, it's that it was an inconsistent language. There were many competing ways of accomplishing things and many of them were mutually exclusive with each other and introduced footguns. It was far far too easy to write code in C++ that looked correct but was utterly broken in very subtle and hard to detect ways. The Go guys looked at that situation and decided the problem was that the language was too complex and had too many features (arguably true), but decided to make the exact opposite mistake by designing a language that was too simple and had too few features.
It is much, much more difficult to make Go run as fast as Rust compared to writing that faster in the first place Rust program.
It’s a fair point that the speed of a language is not everything, but that’s not my point. My point is that with C++, the programmer must often play a puzzle of avoiding common pitfalls with e.g. memory allocation - on top of the actual problem the programmer is intending to solve. This hurts productivity, because there’s so much more to be mindful about.
Both Rust and Go are more free from this kind of extra mental overhead. The programmer can focus more attention on the actual problem. This is probably why Google has observed that both Rust and Go developers are twice as productive than C++ developers.
Go makes the trade off of using garbage collectors, which is easier for programmers to work with but comes with extra performance cost.
Having a simple and verbose language is not necessarily a downside. I’d rather take a simple language over all the syntactic sugar that comes with Perl.
This isn't entirely correct. Rust you do still need to worry about those same problems, it just gives you much better abstractions for modeling and thinking about them, and the tooling of the language "checks your homework" so to speak to make sure you didn't make any mistakes in how you were thinking about it. The upside is that you can be very specific about how you handle certain tasks allowing you to be super efficient with resources. The downside is that you do still need to worry about those resources at least a little bit. If you wanted to you could write Rust like Go by just making every variable a
Box<Arc<...>>
and using.clone()
like mad, but your performance is going to take a hit.Go (and other GCed) languages on the other hand, do entirely free you from having to worry about memory utilization in a general sense as the language runtime takes care of that for you. The downside is that it often does a poor job of doing so, and if you do run into one of the edge cases it's not so great at your tools for dealing with that are severely limited. Further it's very easy to accidentally screw up your memory usage and use far more than is necessary leading to excessive heap churn and serious performance degradation. Because the language makes it easy, even if what you're doing is wrong, and it lacks the tools to alert you to that problem before you trip over it at runtime.
As programmers, our bread and butter is abstractions. We use abstractions because in a very real sense what we do day to day if we removed all the abstractions would be a herculean effort that not even the best of us could manage for any period of time. Go's idea of "simple" is limiting the number of abstractions that the language provides, and so it's up to the programmer to use that small handful to construct more powerful ones. Every code base becomes a snowflake where each team rolled their own solution, or everyone just uses the same sets of libraries that provide the solution. You haven't removed the complexity, you've just shifted it out of the language and onto a 3rd party. It's better to have a consistent set of abstractions provided and maintained by the language and centrally developed by everyone, rather than a hodge-podge of abstractions by random 3rd parties.
I disagree about comparing languages by speed. Just because you can make Go programs as fast as Rust programs, it's not going to be as straightforward as doing it in Rust. I'd much rather spend slightly more effort up front to write idiomatic Rust code that's fast by construction than try to make Go code faster by applying a bunch of arcane tweaks to it.
It is fair to compare speeds, I just think it's probably the wrong argument to focus on if you're trying to convince people of the value of a language. It's definitely a supporting point, but at the end of the day, most programs don't actually need to be blazingly fast, they just need to not be dog slow. Ease of writing (correct) code and even more importantly maintaining and debugging code are generally far more important factors in a languages success, and those are all areas that Rust excels in.
The problem with a purely speed focused argument is that it's always possible to cherry pick examples in both directions. You can find some piece of idiomatic Go code that just happens to be faster than the equivalent idiomatic Rust code and vice versa. The fact that it's undoubtedly much easier to find idiomatic Rust code that out performs most Go code (idiomatic or not) is a much harder argument to use to convince people. The Go proponents will just argue that the ease of understanding the Go code outweighs whatever speed gains Rust has. That's why I think it's important to also point out that Go might be easier to write small snippets of, but for any realistic program it's going to be harder to write and maintain, and it will be more prone to bugs.