Live data from Hacker News

How I went about learning Rust

eli.thegreenplace.net

231–240 of 303 posts

Re: How I went about learning Rust

#231

Serious question: can I just use smart pointer like feature of Rc/Arc combing with Mutex or RWLock instead of fighting borrow checker? I know this practice is shunned upon by Rust purists but I like to see how practical it is in real life and project. Especially around using Rust as a safer but more performant language instead of pushing for ultimate zero-cost abstraction and top notch performance.

Probably, yes. But note that ref counters will leak memory in the presence of cycles.

You need to either ensure that your pointer graphs contain no cycles (in which case you could probably also model it using ownership) or have some strategy for discovering and breaking those cycles (in which case ref counting isn't buying you that much).

In other words, if your data is naturally modeled using ref counts, then, yes, Rc is great. If not, it's not. And it's probably worth noting that most managed languages don't use ref counting, so the set of problems that are naturally modeled that way appears to be relatively small compared to tracing GC.

Re: How I went about learning Rust

#232

Earlier quoted context omitted.

How "large" is the garbage collector penalty? My understanding is that the Go GC is significantly more efficient than for example JS's mark/sweep approach. Apples to oranges for sure, but I am interested in better understanding how expensive the Go GC is vs Rust performance.

Check out the discord article I posted in the original reply. If I interpret the graphs correctly, I see: Golang: * baseline 20% cpu + spikes to 35% once the GC runs. * response times of about 1ms + spikes up to 10ms. Rust: * baseline 12% cpu + flat, no spiking. * response times of 20us + flat, no spiking (!). In terms of scaling, I interpret the results in favor of Rust. My reasoning is the more you run the GC, the…

The question here is how much can you disambiguate between the impact of GC and the impact of differently written code plus differently optimizing compiler backend (where Go is still very simple but Rust uses LLVM). If for example the Go code used goroutines and channels in those places where the rewritten Rust code uses asynchronous operations, that alone may account for substantial differences in performance.

Re: How I went about learning Rust

#233
One great thing about the Rust books and tutorial -- you can easily enjoy them offline, right out-of-the-box.

I learned the basics of Rust on a long plane ride with no WiFi. What a great way to pass the time!

Re: How I went about learning Rust

#234

Earlier quoted context omitted.

Go is fun at first, and then it becomes soul sucking. It's all boiler plate. Many large scale projects have a lack of adequate unit testing, so large code bases are particularly painful to maintain. I attribute this lack of tests due to how the code needs to be structured, you have to needlessly add 'interfaces' throughout your code to accomplish things. Go has it's strengths, but IMO fun isn't one of them. It turns…

I'm in the same position as OP and was wondering the same thing; finding a job using Go. Is the bloat that you see the most related to error checking? If not what else is it?

The bloat is mostly related to mocking and making a fake client for everything for unit tests, and the practices you have to follow to make that actually work.

In Python or Java, you can do something like:

class: f1(): self.some_api_call()

test_class extends class some_api_call():

In go, you cannot do this. Fair enough, but everyone writes object-style code because it's easier and there's less boiler plate. If you do this, you can't write tests.

Instead, you have to do something like:

class: apiMethod = nil f1(): self.apiMethod()

And assign apiMethod when you create the instance of the object; there are no constructors because they're not traditional objects, you need to create a factor method (boiler plate) or build the struct by hand (boiler plate). None of this is terribly challenging in and of itself, but if you work on large code bases, nobody did this because it's extra work, and now you have to refactor it because you want to make a change to the critical business logic and prove you're not introducing a regression (a constraint the l33t coders before you didn't have because they get to go fast and break things).

And finally, often times the thing you need to mock is in someone else's package, and it doesn't implement an interface, or the thing you need to mutate is private, etc, etc. You end up need to mock half of a package sometimes.

None of this is insurmountable, but when you do it day in and day out for years like I did, it's a real slog, and it sucks your soul out of your body. It wasn't uncommon for me to spend literally 20x as long refactoring and implementing tests as it was to ship features. If you look at some unit tests from large go projects, you'll see stuff like struct{struct{struct{struct{...}}},struct{struct{struct{...}}}} because so much stuff needs to be mocked up. And since interfaces are disjointed from classes, you won't know with certainty which methods you need to needlessly mock for your mock class until you try to compile, because the interface is defined somewhere else and not attached to a base class, it's just a definition floating out there in the source somewhere.

Re: How I went about learning Rust

#235

Serious question: can I just use smart pointer like feature of Rc/Arc combing with Mutex or RWLock instead of fighting borrow checker? I know this practice is shunned upon by Rust purists but I like to see how practical it is in real life and project. Especially around using Rust as a safer but more performant language instead of pushing for ultimate zero-cost abstraction and top notch performance.

The main drawback of trying to do this might be that the syntax is unwieldy. If you have one big shared object, or shared objects only in a specific part of your program, it's no big deal, and it arguably helps call attention to what's going on. But if everything is using Arc>, you'll have .write().unwrap() or similar on every line, and it'll feel terrible.

The sibling comment mentioned cycle leaks, and in addition to that I'll add the runtime panics or deadlocks associated with locking the same thing twice.

Re: How I went about learning Rust

#237

Serious question: can I just use smart pointer like feature of Rc/Arc combing with Mutex or RWLock instead of fighting borrow checker? I know this practice is shunned upon by Rust purists but I like to see how practical it is in real life and project. Especially around using Rust as a safer but more performant language instead of pushing for ultimate zero-cost abstraction and top notch performance.

In addition to munificient's response, I'd point out that this will likely have a significant performance cost. Since performance is one of the main reasons of using a low-level language like Rust, it should give you pause.

I'm not saying there's anything bad with Arc + Mutex - they're certainly useful tools and great in some scenarios; it's just that I wouldn't reach out to them just to "avoid fighting the borrow checker". If your code can be written without those tools, it's best to do so.

Re: How I went about learning Rust

#239
post #146

Earlier quoted context omitted.

It is no different than using interfaces, protocols, pure virtual base classes....

It's similar, but there are some differences. Notably, my package can implement my trait for your type, while my package (usually? always?) cannot make your type inherit from my virtual base class.

Wrapper classes should be equally good once Valhalla (jdk) lands, without introducing another pointer indirection.

Re: How I went about learning Rust

#240
post #233

One great thing about the Rust books and tutorial -- you can easily enjoy them offline, right out-of-the-box. I learned the basics of Rust on a long plane ride with no WiFi. What a great way to pass the time!

This sounded interesting but I was confused by what you meant by "the book." Looks like that's how it's commonly referred to https://www.rust-lang.org/learn
Post reply on HN