Live data from Hacker News

Why Discord is switching from Go to Rust

blog.discordapp.com

581–590 of 670 posts

Re: Why Discord is switching from Go to Rust

#581

Earlier quoted context omitted.

VMs with JIT like the JVM are only ever really fast/competitive with C in small numerical micro-benchmarks where the code can be hyper-optimized. Most code will be considerably slower due to a lot of factors. Java in particular is a very pointer-heavy language, made up of pointers to pointers to pointers everywhere, which is really bad for our modern systems that often are much more memory latency than CPU constraine…

This stuff is really hard to pin down though. I've been reading these sorts of debates forever. It's true that pointer chasing really hurts in some sorts of program and benchmark. For sure. No argument. That's why Project Valhalla exists. But it's also my view that modern C++ programming gets away with a lot of slow behaviours that people don't really investigate or talk about because they're smeared over the program…

The costs of languages like C++ also get worse the older a program is.

Without global knowledge of memory lifetimes, maintainers make local decisions to copy rather than share.

Re: Why Discord is switching from Go to Rust

#582

Earlier quoted context omitted.

This is what clicked for me on microservices years back. That the language wasn’t important and if I couldn’t do it in python or C, someone else could in Go or Java or etc. Compared to if I wrote something in house entirely in C... lolno

Once you experience protocol buffers it becomes hard to go back.

How is a serde IDL relevant to microservices? XDR would do just as well, so would JSON.

Re: Why Discord is switching from Go to Rust

#583
post #543

Looks like the big challenge is managing a large, LRU cache, which tends to be a difficult problem for GC runtimes. I bet the JVM, with its myriad tunable GC algorithms, would perform better, especially Shenandoah and, of course, the Azul C4. The JVM world tends to solve this problem by using off-heap caches. See Apache Ignite [0] or Ehcache [1]. I can't speak for how their Rust cache manages memory, but the thing to…

> From a purely architectural perspective, I would try to put cacheable material in something like memcache or redis You cannot use a caching server at that scale with those latency requirements. It has to be embedded

Something like rocksdb (https://rocksdb.org/) then

Re: Why Discord is switching from Go to Rust

#584

Earlier quoted context omitted.

This is what clicked for me on microservices years back. That the language wasn’t important and if I couldn’t do it in python or C, someone else could in Go or Java or etc. Compared to if I wrote something in house entirely in C... lolno

Landing in a shop that uses N programming languages for N microservices would be a pretty miserable experience.

I've seen quite a few environments, and usually there's only a limited current set of tech the devs are allowed to use, and if that's not the case, I try to enforce this, but this set should evolve depending on the needs.

The main issue however is manpower. At my current client, one of the technologies still actively being used for this reason is PHP (which is a horrible fit for microservices for a lot of reasons), because they have a ton of PHP devs employed, and finding a ton of (good) people with something more fitting like Go or Rust knowledge is hard and risky and training costs a lot of money (and more importantly: time)...

Re: Why Discord is switching from Go to Rust

#585

Earlier quoted context omitted.

ARC, used by Swift, has its own cost.

True, but it's generally better than most full GC solutions (for processes running for relatively short times without the benefit of profile-guided optimization), and worse than languages with fully statically analyzable memory usage. Note: that parenthetical is a very big caveat, because properly profile-optimized JVM executables can often achieve exceptional performance/development cost tradeoffs. In addition howev…

> but it's generally better than most full GC solutions

I doubt that. It implies huge costs without giving any benefits of GC.

A typical GC have compaction, nearly stack-like fast allocation [1], ability to allocate a bunch of objects at once (just bump the heap pointer once for a whole bunch).

And both Perl and Swift do indeed perform abysmally, usually worse than both GC and manual languages [2].

> ARC is more of less GC

Well, no. A typical contemporary GC is generational, often concurrent, allowing fast allocation. ARC is just a primitive allocator with ref/deref attached.

[1] http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.49....

[2] https://github.com/ixy-languages/ixy-languages

Re: Why Discord is switching from Go to Rust

#586
post #398

Earlier quoted context omitted.

No offense to Tokio and Rust, I really like Rust, but having someone rewriting their app because of performance limitations in their previous language choice, isn’t really someone picking the right tool for the job necessary. I’m not so sure they would have done the rewrite if the Go GC was performing better, and the choice of Rust seems primarily based on prior experience at the company writing performance sensitive…

too much focus on "business value" often ends-up with codebase in a state that makes delivery of that business value pretty impossible. Boeing was delivering a lot of business value with MAX ...

THIS !!! this is so underrated

Re: Why Discord is switching from Go to Rust

#587
post #264

Earlier quoted context omitted.

In this case, as they were running into the automatic GC interval, their program did not create much, if any garbage. So the CPU overhead for the GC would have been quite small. If you do a lot of allocations, the GC overhead rises of course, but also would the effort of doing allocations/deallocations with a manual managing scheme. In the end it is a bit trade-off, what fits the problem at hand best. The nice thing…

Languages that have GC frequently rely on heap allocation by default and make plenty of allocations. Languages with good manual memory management frequently rely on stack allocation and give plenty of tools to work with data on the stack. Automatic allocation on the stack is almost always faster than the best GC.

GC languages often do and also often do not. Most modern GC languages have escape analysis. So if the compiler can deduct that an object does not escape the current scope, it is stack allocated instead of heap allocated. Modern JVMs do this and Go does this also. Furthermore, Go is way more allocation friendly than e.g. Java. In Go an array of structs is a single item on the heap (or stack). In Java, you would have an array of pointers to separately allocate on the heap (Java is just now trying to rectify this with the "record" types). Also, structs are passed by value instead of reference.

As a consequence, the heap pressure of a Go program is not necessarily significantly larger than that of an equivalent C or Rust program.

Re: Why Discord is switching from Go to Rust

#588
post #36

Earlier quoted context omitted.

Go has a tool for this job. https://golang.org/pkg/sync/#Pool

checked in objects in a sync pool gets cleaned up on GC. It used to clean the whole pool, but now I think it does half each GC cycle. If you want to say "objects checked in should live here forever and not free themselves unless I want them to" sync pool is not the tool for the job.

Well, it's a start. In fact the existing interface lends itself really well to a rolling window on-demand (de)allocator, especially with that New function you can supply.

Just pool could've mitigated your problem at least partially, is what I'm saying.

Re: Why Discord is switching from Go to Rust

#590

Earlier quoted context omitted.

Ugh, linked lists fuck everything up. It’s never the right data structure. Use a vector!

That's only true if you actually need to access more than a few elements at once. And if you never need to insert/delete to/from anywhere but the end.

Even if you need middle inserts but not a B-tree (weird), it’s still better to use a vector in most cases. Time to find the insertion point will dominate.
Post reply on HN