I'm experimenting with creating an actor-based async IRC server on top of
xactor and I'm having problems with how to efficiently get data on and off the network streams.
Specifically, the individual messages I'm dealing with are very small - dozens of bytes each - and trying to use
xactor is putting me in
async_std ecosystem already, so I used that rather than the tokio version) works but very badly. In a test program I wrote where I piped in a 99k-word dictionary and then echoed it out again, using a codec to split out the lines caused a 6-7x slowdown compared to using
AsyncBufReader::lines. Even using
lines, a good 60-70% of the execution time is taken up in the writing the output as opposed to reading or the internal actor processing.
I expect that this slowdown is because the architecture generally expects me to be writing a single item at a time, so all my time is being wasted in the overhead of actually setting up the writes vs the transfer of <12 bytes at a time. I'd expect to be able to fix this just by buffering multiple item and only submitting a proper IO call when I've accumulated a significant amount of data, just like the same problem in a sync context.
My problem is, I have no idea how to do this in an async context - particularly the problem of making sure my buffer doesn't get "stuck" if no new output arrives for a while - or whether there is any library that can effectively deal with this case. If there isn't, I'm not averse to learning how to do it from scratch, but I would have no idea where to even start learning, having never written a direct implementation of
Future et al before rather than dealing with async functions and combinators.
Does anyone have any suggestions for either how to directly solve this problem, or where to learn enough to do it myself?