←back to thread

159 points mpweiher | 1 comments | | HN request time: 0s | source
Show context
franticgecko3 ◴[] No.43672638[source]
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.

replies(3): >>43672735 #>>43673161 #>>43673898 #
mrkeen ◴[] No.43673161[source]
According to the article, channels are slow because they use mutexes under the hood. So it doesn't follow that channels are better than mutexes for large N. Or is the article wrong? Or my reasoning?
replies(1): >>43674787 #
1. franticgecko3 ◴[] No.43674787[source]
I have replied to another comment with more details: the channel mutex is not the same one that sync.Mutex is using.

The article that the OP article references does not show the code for their benchmark, but I must assume it's not using a large number of goroutines.