This is not to say that channel sends are very inefficient. It's just
that everything else you're doing is pretty fast, so the channel sends
are very noticeable and probably not a good choice in this case if
you're worried about speed.
A few other comments on the code:
Use range where you can. Your sum1 and sumSlice functions can be
shorter and faster by ranging over c and cSlice, respectively.
sumSlice can also range over the slice itself.
Your closure goroutines in slow and fast probably don't need to be
goroutines or closures, either. You can just inline the code, drop the
go, and get the same effect.
- Evan
Channels become a bottleneck if you pass a lot of individual items
through them.
You can work around this by packing chunks of data into arrays and
then unpacking on the other end. This is literally 10x faster. The
weird thing is, you'd think it would be slower with all those extra
steps. The following code demonstrates this effect:
It will also complicate the mental model for channels beyond being a
convenient way to do the co-routine bookkeeping. One of the nicest
things about Go is it 'fits in your head'.
--
Dr Rich Wareham
Hi Dmitry. I agree with what you're saying about real-life production
code. But, with the caveat that real-life production code has been
written with an awareness of this issue, and so already applies the
hand-optimization of packing large data streams into chunks before
passing them over channels, or it eschews channels altogether.
I don't pretend that my particular suggestion for re-implementing
channels should direct future development of the language. It was just
the first thing that occurred to me.
What I would like to get from this discussion is some technical
opinions on the what-if question: What if I wanted to make channels
and goroutines the most efficient (and therefore default) way to
organize the data path? How might I do that?
Whether it's useful to do so is another topic. But, to give my
synthetic microbenchmark some plausibility, I'd like to suggest that
channels are the signal feature of Go, in the same way that regular
expressions are the signal feature of Perl. If I was writing a program
that needed to scan gigabytes of text, line-by-line and capture
certain tokens, I would look no further than writing three lines of
Perl, because the syntax and execution are tuned so perfectly for that
domain, that I would never find a better solution in any number of
lines of code in another language. Similarly if I was writing a
molecular-dynamics simulator which was multi-threaded in order to
spread the load across many processors I would find Go channels to
embody the ideal syntax, but it would take a lot of tuning to wring
the performance out of it and meanwhile, I'd be wondering if Boost or
OpenMP might make more sense.