I don't understand why they felt necessary to rewrite a core component in another language. If you have a garbage collection problem my first intuition would be to produce less garbage!
For example better using the stack, or pulling out the big gun of manual memory management.
I'm sure they had reasons to choose Go when they first designed this project but they don't go into them at all.
Feels like they just wanted to play with a new toy.
> If you have a garbage collection problem my first intuition would be to produce less garbage!
FTA:
“These latency spikes definitely smelled like garbage collection performance impact, but we had written the Go code very efficiently and had very few allocations. We were not creating a lot of garbage.
[…]
the spikes were huge not because of a massive amount of ready-to-free memory, but because the garbage collector needed to scan the entire LRU cache in order to determine if the memory was truly free from references”
They explained in the post why this wasn't an issue: they were producing very little garbage, but there was a very large object graph.
> manual memory management
If you need to do manual memory management in a GC language with no builtin support for it, like Go, that's probably a sign that you should switch to a different language.
And importantly in a tracing GC the work load is a function of the non-garbage data not of the garbage.
Generational GC can avoid some of it by ignoring the old code entirely, but Go does not implement generations because its relatively strong ability to stack-allocate generally replaces the nursery, and for most work loads you don’t recoup the costs.
Problem with languages like Go is, because they have GC, their API is less tuned to the ability to prevent new allocations.
In C you see lots of functions whose first parameter is a buffer that will be re-used.
And even in Rust you don't see this often, because reusing a buffer means having to do &mut, which means having to re-structure your code. And it's really easy to do Vec::new().
One of big issue with GC is it need to scan every reachable objects to mark it is reachable. That mean even if your code produce no garbage but have a large amount of long lived object the GC still need to traverse all of those objects every cycle.
For example better using the stack, or pulling out the big gun of manual memory management.
I'm sure they had reasons to choose Go when they first designed this project but they don't go into them at all.
Feels like they just wanted to play with a new toy.