Hacker News new | past | comments | ask | show | jobs | submit login

For some scenarios channels and mutexes are both suitable for, mutextes are a bit more performant than channels. If you do care about the performance penalty, just choose mutexes. But the for scenarios mutextes are incapable of, still using mutexes is surely not a good idea.



This would be a good thing to add to the reference.


Dunno. Tell people "channels are about 3 times slower than mutexes" and watch them scramble the hell out of their program trying to avoid channels, when the reality is "in general, both of them are fast enough that they will not be the bottleneck on your program".

In general (not just Go!), don't send tiny amounts of work across any sort of internal boundary (goroutine, thread, spark, green thread, whatever they call it). The amount of work you send should significantly exceed the costs of sending it. Follow this advice and the perf differences between mutexes and channels will almost certainly not be relevant; fail to follow it and neither of them will be fast enough. I don't think there's actually a lot of programs in the wild where the performance difference between the two would be the make-or-break difference. Non-zero, but not many. In practice it's pretty clear developers will spend much more time worrying over it than is justified.

(A common benchmark I see new programmers apply to any language that claims to be good at multithreading is to try to "parallelize" the act of adding a few million integers together by sending individual integers or addition problems out to threads, and wondering why it's 10-100 times slower even though all my CPUs are at 100%, so why does multithreading suck so hard in this language? The problem is that no matter how cheap the send operation is, it's going to be dozens or hundreds of operations, whereas a single integer addition is generally a single cycle, or possibly, amortized to less than that depending on how good your compiler is. You just need to be sure to send units of work larger than the cost of sending them, which is generally not that hard. This isn't just Go, I've seen this charge leveled at Haskell, Erlang, and Python's multiprocessing too, and I'm sure others have seen it in their own communities. It's a very common mistake.)


The amount of work you send should significantly exceed the costs of sending it.

Jerf, you did it again! This is gold! Succinct and to the point.

I'm going to think on this one.


This implies that you know the "costs of sending it."


For channels and other things in the local OS process, you should have a good idea. Give or take being in major swap problems, etc., but I think of that as an "already lost" situation; at that point the problem isn't the expense of moving things between threads or local processes anyhow.

When you get out into discussing network matters, it gets a lot fuzzier. You may "know" that you're only .025ms away from something in some specific system, but your TCP-based API doesn't necessarily "know" that and will happily use the exact same code to do something that takes 4 orders of magnitude larger. That's enough difference to be problematic.


'Send'ing things via a Go channel is all in the same process, between goroutines (sometimes between threads).




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: