Live data from Hacker News

Taming Go’s memory usage, or how we avoided rewriting our client in Rust

akitasoftware.com

1–10 of 231 posts

Re: Taming Go’s memory usage, or how we avoided rewriting our client in Rust

#2
Bit confused by this part of the article:

> PRO-REWRITE: Rust has manual memory management, so we would avoid the problem of having to wrestle with a garbage collector because we would just deallocate unused memory ourselves, or more carefully be able to engineer the response to increased load.

> ANTI-REWRITE: Rust has manual memory management, which means that whenever we’re writing code we’ll have to take the time to manage memory ourselves.

Isn't part of the point of Rust that you don't manage memory yourself, and rather that the compiler is smart enough to manage it for you?

Re: Taming Go’s memory usage, or how we avoided rewriting our client in Rust

#3
post #2

Bit confused by this part of the article: > PRO-REWRITE: Rust has manual memory management, so we would avoid the problem of having to wrestle with a garbage collector because we would just deallocate unused memory ourselves, or more carefully be able to engineer the response to increased load. > ANTI-REWRITE: Rust has manual memory management, which means that whenever we’re writing code we’ll have to take the time…

I feel that this is one of those common misconceptions about Rust. Rust's memory management is nothing like C or non-modern C++'s with malloc/free or new/delete. Rust uses modern-C++'s RAII model, typically, to allocate memory. The compiler is smart enough to know when to call drop() (which is essentially free/delete, but with the possibility of additional behavior). You can also call drop() yourself.

What I think people _should_ focus on with Rust versus Go (et al) is that Rust allows you to choose where you _place_ memory. You can choose the stack or the heap. The placement can matter in hot regions of code. Additionally, Rust is pretty in-your-face when it comes to concurrency and sharing memory across thread/task boundaries.

Re: Taming Go’s memory usage, or how we avoided rewriting our client in Rust

#4
> But our profile wasn’t ever showing us 500GB of live data, just a little bit more than 200MB in the worst cases. This suggested to me that we’d done all we could with live objects.

Is this a typo? Weren't seeing 500 MB of live data, just a little more than 200MB in the worst case?

EDIT: Btw, I read the entire article. It was fascinating, thank you!

Re: Taming Go’s memory usage, or how we avoided rewriting our client in Rust

#5
post #2

Bit confused by this part of the article: > PRO-REWRITE: Rust has manual memory management, so we would avoid the problem of having to wrestle with a garbage collector because we would just deallocate unused memory ourselves, or more carefully be able to engineer the response to increased load. > ANTI-REWRITE: Rust has manual memory management, which means that whenever we’re writing code we’ll have to take the time…

Yes, Rust kinda doesn't fit super cleanly into a very black/white binary here. It is automatic in the sense that you do not generally call malloc/free. The compiler handles this for you. At the same time, you have a lot more control than you do in a language with a GC, and so to some people, it feels more manual.

It's also like, a perception thing in some sense. Imagine someone writes some code. They get a compiler error. There are two ways to react to this event:

"Wow the compiler didn't make this work, I have to think about memory all the time."

"Ah, the compiler caught a mistake for me. Thank goodness I don't have to think about this for myself."

Both perceptions make sense, but seem to be in complete and total opposition.

Re: Taming Go’s memory usage, or how we avoided rewriting our client in Rust

#6
post #2

Bit confused by this part of the article: > PRO-REWRITE: Rust has manual memory management, so we would avoid the problem of having to wrestle with a garbage collector because we would just deallocate unused memory ourselves, or more carefully be able to engineer the response to increased load. > ANTI-REWRITE: Rust has manual memory management, which means that whenever we’re writing code we’ll have to take the time…

You are still managing memory in Rust, it’s just more constrained, statically checked and inferred. Within those constraints you have full control.

Re: Taming Go’s memory usage, or how we avoided rewriting our client in Rust

#7
post #4

> But our profile wasn’t ever showing us 500GB of live data, just a little bit more than 200MB in the worst cases. This suggested to me that we’d done all we could with live objects. Is this a typo? Weren't seeing 500 MB of live data, just a little more than 200MB in the worst case? EDIT: Btw, I read the entire article. It was fascinating, thank you!

[deleted]

Re: Taming Go’s memory usage, or how we avoided rewriting our client in Rust

#8
Rebuilding in a different language is just trading one problem set for another. Better using the tools you've already taken on is a much better strategy if you don't have the money to hire a whole new set of devs or a year to burn onboarding onto a new language.

Re: Taming Go’s memory usage, or how we avoided rewriting our client in Rust

#9
post #2

Bit confused by this part of the article: > PRO-REWRITE: Rust has manual memory management, so we would avoid the problem of having to wrestle with a garbage collector because we would just deallocate unused memory ourselves, or more carefully be able to engineer the response to increased load. > ANTI-REWRITE: Rust has manual memory management, which means that whenever we’re writing code we’ll have to take the time…

> Isn't part of the point of Rust that you don't manage memory yourself, and rather that the compiler is smart enough to manage it for you?

For trivial cases, kind of. But once you start to do anything remotely sophisticated, no. Everything you do in Rust is checked w.r.t. memory management, but you still need to make many choices about it. All the stuff about lifetimes, borrowing, etc: that's memory management. The compiler's checking it for you, but you still need to design stuff sanely, with memory management (and the checking thereof) in mind. It's easy to back yourself into a corner if you ignore this.

Re: Taming Go’s memory usage, or how we avoided rewriting our client in Rust

#10
Buried in here are great examples of why rewrites don’t help:

“The module that does this inference was recompiling those regular expressions each time it was asked to do the work.”

“The reason for the allocation was a buffer holding decompressed data, before feeding it to a parser. …the output of the decompression could be fed directly into the parser, without any extra buffer.”

The problem here isn’t that the language has GC, it’s that memory usage was just not considered. If you want performance, you have to pay attention to allocations no matter what kind of memory management your language has. And as the article demonstrates, if you pay attention, you can get performance no matter what kind of memory management your language has.

Post reply on HN