4 ms·
I recently wrote a program that used rayon to do a multithreaded but heavily I/O-bound computation. It was super simple to write that and get it working. It exe
by antonvs 4y ago
I recently wrote a program that used rayon to do a multithreaded but heavily I/O-bound computation. It was super simple to write that and get it working. It executed hundreds of millions of tasks, but you just tell rayon how big the thread pool should be and execute everything on a parallel iterator. It looks just like single-threaded code. As simple as this sort of thing can be.
But in theory, because of the I/O, it should be much more efficient to run this async. So I tried doing it async on a single thread to start with. That was a bit more difficult to get working, just because of all the messiness around async. And it was much slower because of the single thread.
I then tried to get that working with multiple threads. That proved problematic. I tried libraries like par_streams but ran into issues. I ended up using Tokio’s buffered_unordered to get a simpler setup with a pool of Tokio tasks.
This ended up giving quite unpredictable performance and being very heavy on memory usage. It seemed like it was going to need quite a bit of tweaking to get it to work as smoothly as the multithreaded version. I ended up abandoning it, since I didn’t have time to debug the black box of Tokio’s internal scheduling.
The lesson I took from this is that unless you have a really strong need to use async, multithreaded is going to be a lot easier and more reliable to implement, and the code will be much more transparent, not littered with awaits and complex Future type signatures.