4 ms·
For the threading difference, do you mean that Rust needs 'normal' threads plus async/await support, but Go can just lean on its built in concurrency support fo
by sime2009 7y ago
For the threading difference, do you mean that Rust needs 'normal' threads plus async/await support, but Go can just lean on its built in concurrency support for both cases? i.e. Go threads instead of explicit async style code.
- littlestymaar 7y agoYour sentence implies that Go green threads can do both of what 1:1 threading and async/await can, but it's more complex than that: there's a tradeoff between the simplicity (only one concurrency primitive) and the capability of the said primitive: - with it's M:N model, Go cannot really do FFI efficiently, while both 1:1 async/await have no problem with that in Rust. - goroutines are cooperatively scheduled, while OS thread are preemptively scheduled. If you have hot loops, Go's model won't be able yo guarantee fairness between goroutines, which may be a problem depending on your usage. OS threads don't have this problem. - with goroutines you won't achieve the level of performance you can reach with async/await. Go and Rust fills a different niche of programming and take a different stand on this tradeoff: Rust gives you more power at a complexity cost. Go offers you more simplicity, with less power.
- kjksf 7y agoThe reason cgo is (relatively) slow is small stacks, not M:N threading. Small stacks (and M:N threading) are needed to efficiently implement tens of thousands of goroutines. CGO is slow mostly because it needs to switch to a larger stack when calling a C function. It's a trade-off. A different Go implementation could make Goroutines map 1:1 to threads and have fast cgo calls at the expense of slow goroutines. Rust is not exempt from those trade-offs. They chose fast FFI and smaller runtime. They paid with slow threads. Async/await promises to be the best of both worlds but it comes at a cost of great complexity, both for the programmer and the implementor. At the end of the day under the covers it's just threads that need to be managed in a complex and often invisible way plus a complex rewrite of your straightforward code into a mess of a state machine. I can confidently say that learning to use goroutines took 10x less time than learning async/await in C#. I understand goroutines better than I ever understood async/away.
- pcwalton 7y ago> Small stacks (and M:N threading) are needed to efficiently implement tens of thousands of goroutines. Tens of thousands of threads are no problem with 1:1 threading on Linux. > They paid with slow threads. I would not call 1:1 threads "slow threads". If they were slow, then the 1:1 NPTL would have not defeated the M:N NGPT back in the day when this was being debated in the open source OS community. > complex rewrite of your straightforward code into a mess of a state machine. The entire point of async/await is that you don't have to do a complex rewrite of your straightforward code. It remains straightforward, and the compiler does the transformation for you.
- Thaxll 7y ago> tens of thousands of threads are no problem with 1:1 threading on Linux Yes it's a problem, even on modern kernel, memory, context switch ... there is a reason why high performance code uses small thread pool.
- masklinn 7y agoGiven the context, it's not a memory problem was implied, because small stacks are not actually relevant, because C stacks are not committed upfront (at least on unices, not sure about linux). So your threads are more likely to take up a page each (plus kernel datastructure overhead) than the 8MB allowed to a C stack.
- littlestymaar 7y ago> It's a trade-off. Yes, That's exactly my point. > I can confidently say that learning to use goroutines took 10x less time than learning async/await in C#. It's a matter of preferences, I've always preferred async/await to threads because you don't need to juggle with channels and you're way less likely to cause a deadlock. > it comes at a cost of great complexity, both for the programmer and the implementor. Is that really harder to implement than a M:N runtime like Go's? > The reason cgo is (relatively) slow is small stacks, not M:N threading. You're picking nits here. Without small stacks there would be no point using M:N threading in Go… And Cgo is not only relatively slow: most of the time it is slow enough to destroy all performance benefit of calling a FFI function. It's a pretty big deal.