Open jprafael opened 8 years ago
I would have to look more into it, but I'm aware that sync channel has a naive implementation using yield_now
in both producer and consumer and the only notification is on channel becoming non-empty from producer to consumer. The consumer should definitely send a notification to producer, when the channel is no longer full. My guess right now is that is the root of the problem, combined with 100ms default tick + a mio bug that makes it effectively 200ms
I'll look into that at some point, but I'm always happy to accept PRs. :)
Not sure if this should be considered a performance issue or a bug.
Consider the following test case
This example shows a normal pattern where there is a producer that is decoupled from a consumer by a bounded queue (the sync_channel).
It is expected that when the queue is full, either because consumer is slow or hasn't been scheduled as often, that the producer blocks. Later, when there is enough space the producer gets resumed.
However, running the above code you can see that the "throughput" is somewhat surprisingly just 2 per second. Most likely, when the producer coroutine gets yielded (src/sync/mpsc.rs:238) the event loop thinks there is nothing left to do and starts blocking on IO (for some ms). In this case, the consumer coroutine is ready to be executed and the event loop should have either skipped the io_poll() entirelly, or done it with a 0 timeout.
If you are wondering, increasing the queue size to 2 does increase the throughput. But the result is a lot higher than just 2x. If the scheduling gods make it so that the two courotines are alternating requests to the queue then the limit is never hit, and they are able to proceed at full CPU speed.