Sync I/O lets your process (not thread) do something else. In other languages, async I/O is faster because it avoids context switches and amortizes
kernel crossings. Apparently this is not the case in practice for python.
This doesn’t surprise me at all, as I’ve had to deal with async python in production, and it was a performance and reliability nightmare compared to the async Java and C++ it interacted with.
The point is that async IO allows your own process/thread to progress while waiting for IO. Preemptive multitasking just assigns the CPU to something else while waiting, which is good for the box as a whole, but not necessarily productive for that one process (unless it is multithreaded).