4 ms·
Ugh. This is only going to mislead newbies and irritate the experienced people who will end up reviewing their code. Channel sends and receives have non-trivia
by perfmode 8y ago
Ugh. This is only going to mislead newbies and irritate the experienced people who will end up reviewing their code.
Channel sends and receives have non-trivial costs associated with them.
When you choose to model your problem with channel communication, you better be sure you’re doing enough work before and/or after the send/recv to justify involving the scheduler.
I’ve reviewed code where new engineers spawn unbounded goroutines... for each goroutine to then go on to compute the distance between two points on a two dimensional plane... aggregate the results on a channel and compute a sum.
- zzzcpan 8y agoSay channels were always low overhead, two orders of magnitude faster in general or optimized out completely in cases where even that overhead was too much. Would it still make a difference? I believe performance is only a small part of the problem, channels in Go are just too awkward to use.
- swiley 8y agoI haven't done a ton of go programming but the last small web app I wrote we sent closures over a channel to serialize access to a sqlite database. Channels felt like a nice clean way to handle that.
- perfmode 8y agoThat’s really cool.
- iainmerrick 8y agoYes, sending closures over channels is a very convenient and flexible concurrency framework. In fact it would be handy for all channels to have a standard handler attached, that pulls closures from the channel and executes them. Among other benefits that would mean you didn’t need a separate “go” keyword; to execute a function in the background you just post it to a channel. That’s basically how Java thread pools and Grand Central Dispatch work. The idiom of defining message types that you post to a channel so that you can pull them from the channel and execute them strikes me as boilerplate. What you really want to do is run some code in a particular thread context; so why not just do that directly? Are there useful things you do with channels that can’t easily be done with thread pools?
- weberc2 8y agoThey’re too awkward to throw at every problem, but they are definitely useful for things like serialization. The ergonomics could be improved, however.
- bowmessage 8y agoThe author does call this out: > While it certainly looks like an interesting technique, for our particular use case this approach seems like an overkill. In fact, overuse of channels is one of the common gotchas for Go beginners. Quoting from the Go Wiki entry: > > Most locking issues can be solved using either channels or traditional locks. > So which should you use? > Use whichever is most expressive and/or most simple. It then goes on to suggest that mutexes are preferable for protecting shared state. I tend to agree, since a mutex feels more natural here.
- chrisseaton 8y agoLike how compilers can choose to not actually not emit a method call when you have a method call in your source code and instead just inline the code from the method, could the Go compiler chose to not actually write to a channel and just instead run the action of the goroutine where it receive from the channel at that point? The scheduler semantics would allow that wouldn't they?
- eikenberry 8y agoCSP is one of Go's killer features and it is going to get overused by newbies regardless of this article. But that is part of the process that everyone goes through learning a new language and hopefully the experienced people will try to be good mentors and help them gain a more balance view of their use and not get irritated.
- phamilton 8y agoI find it to always be either overused or underused. Either the app is a vanilla evented io web application, in which case you could write it in pretty much any major language using an evented framework. Or it's a mess of buggy channel usage. I guess there's a happy balance of "let the library maintainers do the hard channel work" but to be honest I can use someone else's high performance evented io library in any language.
- eikenberry 8y agoMy experiences doesn't reflect yours exactly, but I know what you mean. Go is still a fairly young language, so I think the patterns are still establishing themselves. But I think progress is being made and much of the code I've seen lately has been pretty good. Regarding libraries, best practice is to use CSP sparingly and to design the API as blocking calls so the applications have the choice of using the call directly or wrapping it with CSP.
- iainmerrick 8y agoWould it be fair to say it should be rare to see channels passed directly in the parameters or return types of a public API? If so, it feels to me like channels are a bit of a misfeature. They work OK as a way to implement concurrency, sure, but not in a way that you want to expose in your API. They’re not very composable. (That’s a bit hand-wavy as I’m not a heavy Go user. If there are good uses of channels in public APIs I’d be interested to hear about them.) Compare to e.g. maps, or closures. Those are very generally useful and composable primitives and it’s therefore common to see them used directly in APIs.