Very neat visualizations! Really good way to demonstrate the underlying principles. Great article.
I will add one thing: the author makes much of how problematic CPU-intensive tasks are. That's true, but also: if you need to do a CPU-intensive operation, you need to tie up a CPU to do it, there's no getting around it. What you might want to do is break the computation up in to smaller chunks with `.await`s sprinkled in there or dispatch it to a background thread, but at some point you have to pay the cost in CPU time.
What is much more problematic is blocking I/O operations. That also ties up a CPU and blocks the event loop, but for no good reason. All the CPU is going to be doing is sleeping waiting for the network or hard-drives or whatever it is to do it's work, when it could be doing other useful things, processing other events. That kind of thing leads to huge under-utilization of your resources, and it kills your concurrency.
This means you really can't mix async I/O with blocking I/O: if you go async, ALL your I/O operations need to be async. Or you have to do it off the event loop in a background thread or something, but then you're losing all the benefits of using async in the first place.
Very neat visualizations! Really good way to demonstrate the underlying principles. Great article.
I will add one thing: the author makes much of how problematic CPU-intensive tasks are. That's true, but also: if you need to do a CPU-intensive operation, you need to tie up a CPU to do it, there's no getting around it. What you might want to do is break the computation up in to smaller chunks with `.await`s sprinkled in there or dispatch it to a background thread, but at some point you have to pay the cost in CPU time.
What is much more problematic is blocking I/O operations. That also ties up a CPU and blocks the event loop, but for no good reason. All the CPU is going to be doing is sleeping waiting for the network or hard-drives or whatever it is to do it's work, when it could be doing other useful things, processing other events. That kind of thing leads to huge under-utilization of your resources, and it kills your concurrency.
This means you really can't mix async I/O with blocking I/O: if you go async, ALL your I/O operations need to be async. Or you have to do it off the event loop in a background thread or something, but then you're losing all the benefits of using async in the first place.