2 ms·
The fact that the author talks about using threading or M:N parallelism if he needed additional performance makes me think he doesn't really understand the use
by seanhunter 3y ago
The fact that the author talks about using threading or M:N parallelism if he needed additional performance makes me think he doesn't really understand the use case for asynchronous programming. Async is specifically for the (very common) situation where a program has many clients (or servers) it needs to talk to but can't make progress efficiently because it spends a lot of time blocked on I/O. You can therefore handle these connections very efficiently without parallelism leaving other cores available to do other things. Threading and other parallelism techniques don't solve that same dillemma. If you create a large number of threads they will still be blocked on I/O waiting for clients or the network typically, and the existence of the GIL in python just makes the case for efficient multiplexing of I/O bound processes in single-threaded code (ie async) stronger. In the threaded case you have spent system resounces to create multiple threads that can't actually function in parallel (because they are blocked on I/O at least as often as the async event loop would be) and are now also sometimes blocked on the GIL.
Having decided that async is appropriate, the question is how you express that in a language or framework. I've used several approaches, from the magical "don't worry about it we'll just make it work for you" type of approach that he seems to advocate with gevent, to things like the callback-based approach of old Twisted (back in the days that python was a scrappy little upstart rather than this globally ubiquitous language). They are all equivalent from the machine's point of view more or less, but I find the async model easier to reason about and therefore easier to debug. This seems largely a question of taste. It's absolutely not the case that (as the author claims) the async versions of libraries are literally the same with just the word 'async' added into the function definitions. To take synchronous code and make it async, you have to reason about where your program spends its time, what parts of computation you can put into a future vs which parts belong in a seperate task etc. You can't just 's/def/async def/' add a few "awaits" and you're done.
- seanhunter 3y agoThe performance benefits can be very real if used well btw. As an example I have a request-heavy piece of code that used to take > 16hrs to run which took about 2.5mins once changed to async, and that's with adding rate limiting etc so I'm not flooding external servers with requests.