I'm trying to understand coroutines for single threaded concurrency. I'm
surprised that produce()/consume() and RemoteRef have no mechanism for type
information, and as I understand it, are type unstable. One should
therefore avoid using these in inner loops I guess? Should we expect this
to remain the case?
In Go it appears to be encouraged to heavily use concurrency even for
things as simple as generating a series of numbers. In julia you might say
a = zeros(Int,100)
for i=1:100 a[i]=i end
In go you could certainly do that, but in my brief introduction it appeared
to be encouraged to do create a function that pushes i onto a "channel" and
then read numbers out from the channel. In julia with produce/consume
instead of a channel that would look like
counter() = for i=1:100 produce(i) end
a = zeros(Int,100)
task = Task(counter)
for i=1:100 a[i]=consume(task) end
This seems seems to violate julia performance guidelines as I understand
them, since the the compiler doesn't know what type consume(task) will
return.
So I tried to implement something more like a go channel, that has type
information. I thought it would be faster
type GoChannel{T}
v::T
hasvalue::Bool
c::Condition
end
It turned out to be about 2x slower than the produce()/consume() approach,
and using RemoteRef (which has a more go channel like API) is about 4x
slower than produce()/consume(). On my computer anyway, the
produce()/consume() approach is about 7x slower than using a channel in go
for the same thing.
Gist with full code: https://gist.github.com/ggggggggg/c93a0f029620deca4f2e
So I guess my questions are:
Why isn't there at least an option to encode type information in
consume/produce and RemoteRef?
Is there anything I could do to speed up my GoChannel implementation? Did I
make any mistakes in my other benchmarks?
I know this is one of go's defining features, so it is perhaps
unsurprising that Julia isn't as fast for this yet. Is there room to speed
these concurrent communication constructs up?
Thanks.