| I'd like to refute the 'channels are slow' part of this article. If you run a microbenchmark which seems like what has been done, then channels look slow. If you try the contention with thousands of goroutines on a high core count machine, there is a significant inflection point where channels start outperforming sync.Mutex The reason is that sync.Mutex, if left to wait long enough will enter a slow code path and if memory serves, will call out to a kernel futex. The channel will not do this because the mutex that a channel is built with is exists in the go runtime - that's the special sauce the author is complaining doesn't exist but didn't try hard enough to seek it out. Anecdotally, we have ~2m lines of Go and use channels extensively in a message passing style. We do not use channels to increment a shared number, because that's ridiculous and the author is disingenuous in their contrived example. No serious Go shop is using a channel for that. |
> sync.Mutex, if left to wait long enough will enter a slow code path and if memory serves, will call out to a kernel futex. The channel will not do this because the mutex that a channel is built with is exists in the go runtime
Do you have any more details about this? Why isn’t sync.Mutex implemented with that same mutex channels use?
> [we] use channels extensively in a message passing style. We do not use channels to increment a shared number
What is the rule of thumb your Go shop uses for when to use channels vs mutexes?