Live data from Hacker News

Python Asyncio

superfastpython.com

141–150 of 188 posts

Re: Python Asyncio

#141

Earlier quoted context omitted.

Can you give me an example which languages do this?

In Kotlin for instance you can execute your coroutines with different "dispatchers", which have different behaviors. You can for instance use a dispatcher with multiple threads in a threadpool, run it in the main thread, a specific thread, in threads with low/high priority etc. Basically allowing you to write code using the async/coroutine paradigm, but then control its execution from the outside. So I've also used c…

> In Kotlin for instance you can execute your coroutines with different "dispatchers", which have different behaviors. You can for instance use a dispatcher with multiple threads in a threadpool, run it in the main thread, a specific thread, in threads with low/high priority etc. Basically allowing you to write code using the async/coroutine paradigm, but then control its execution from the outside.

I'm not very experienced with Kotlin, but that sounds similar to python's run_in_executor [1]

[1] https://docs.python.org/3/library/asyncio-eventloop.html#asy...

Re: Python Asyncio

#142

Earlier quoted context omitted.

Choosing fastapi for a fast api is a mistake?

Choosing unnecessary complexity for a simple task is a mistake. FastAPI is not faster than Django or Flask for a single request, quite the opposite.

There are other valid reasons than speed:

https://christophergs.com/python/2021/06/16/python-flask-fas...

Re: Python Asyncio

#143

After 2 years of using asyncio in production, I recommend to avoid it if you can. With async programming, you take the complexity of concurrent programming, which is way harder than you can imagine. Also nobody mentions this for some reason, but asyncio doesn't make your programs faster, in fact it makes everything 100x SLOWER (we measured it multiple times, compared the same thing to the sync version), but makes you…

I've experienced something similar using asyncio as well, but I think you're wrong to blame the inherent complexity of concurrent programming. I've used curio as an alternative concurrent programming engine for a med-large project (and many small ones). In comparison to asyncio, it's a joy to use.

What I'm saying if you don't need concurrency, don't trade off simplicity. For REST APIs and websites, probably not needed.

Re: Python Asyncio

#144
post #7

Maybe off-topic, but my advice would be: if you need this guide, consider to switch to another language, if that's possible. In our company we switched to Go, and all those asyncio problems were magically solved.

I love Python and fully agree with you. :(

Re: Python Asyncio

#146

Earlier quoted context omitted.

My opinion is that async/evented is a (useful) performance hack. You wouldn't do it that way for any reason other than you can get better performance than way than by using threading or other pre-emptive multitasking. It's not a better developer experience than writing straight forward code where threads are linear and interruptions happen transparently to the flow of the code. There are foot guns everywhere, with lo…

"Performance" is too wide a term, asyncio does not improve performance in the most widely understood interoperation, "speed". Talking about performance benefits of asyncio causes people to misunderstand where it is best used. "Scalability" is a better word to use when talking about asyncio. Along with describing complex concurrent programming such as for a GUI, where the added syntactical complexity if outweighed by…

Yeah, talking speed in the manner of C1M sorts of things. Server stuff - where python tends to be rather than GUI side. It's demonstrably faster for IO to not be context switching with threads -- but if threads were equal weight to events, I don't the event programming style being more programmer productive than the threaded style. I can see where events are useful in a GUI context, but UI Thread + thread pool dispatch still works well, if your framework supports it.

Just this week, I got to the bottom of a performance issue in django because the developers were using async, and then doing eleventy billion db queries to import a big csv, thereby blocking all other requests.

One of the questions I ask on our programming interviews is "how would you make this (cpu bound) thing go faster" -- Async is definitely a low quality answer to that, when things like indexing or hash lookup vs array scan are still on the table.

Re: Python Asyncio

#147
post #114
post #95

Earlier quoted context omitted.

You need to run the executor somewhere ( loop.run_forever() or loop.run_until_complete() ), that can be in the current thread or a separate thread, keep in mind Python is still conceptually a single core. Things I've found particularly useful: * Optional / debug logging of coroutine start/exit. * Stats logging, including count, runtime, request queue (multiple instances of the same function) depth. * Printing traceba…

I think I hit a foul ball there, as run_in_executor() is for a threadpool. So yeah you are running inside of run_forever() or run_until_complete(), we just don't see it here, and that's where your sending things to run in a different thread. ;-)

Ah got it, thanks for the correction and info.

Re: Python Asyncio

#148
I hope to learn how to use async code more effectively. Coroutines are very interesting. Structured concurrency is very useful in defining understanding concurrency. I wrote a multithreaded userspace scheduler in Java C and Rust which multiplexes lightweight threads over kernel threads. It is a 1:M:N scheduler with 1 scheduler threads M kernel threads and N lightweight threads. This is similar to golang which is P:M:N

https://GitHub.com/samsquire/preemptible-thread

I am deeply interested in parallel and asychronous code. I write about it on my journal (link in my profile)

I am curious if anybody has any ideas on how you would build an interpreter that is multithreaded - with each interpreter running in its own thread and sending objects between threads is done without copying or marshalling. I I think Java does it but I am yet to ask how it does it. Maybe I'll ask Stackoverflow.

I wrote a parallel imaginary assembly interpreter that is backed by an actor framework which can send and receive messages in mailboxes.

Here's some code:

   threads 25
   
   mailbox numbers
   mailbox methods
   set running 1
   set current_thread 0
   set received_value 0
   set current 1
   set increment 1
   :while1
   while running :end
   receive numbers received_value :send
   receivecode methods :send :send
   :send
   add received_value current
   addv current_thread 1
   modulo current_thread 25
   send numbers current_thread increment :while1
   sendcode methods current_thread :print
   endwhile :while1
   jump :end
   :print
   println current
   return
   :end
This is 25 threads that each send integers to eachother as fast as they can. The sendcode instruction can cause the other thread to run some code. It can get up to 1.7 million requests per second without the sendcode and receivecode. With method sending it gets ~600,000 requests per second

Re: Python Asyncio

#149

There is very little in everyday Python usage that benefits from Asyncio. Two in webdev, are long running request (Websockets, SSE, long polling), and processing multiple backend IO processes in parallel. However the later is very rare, you may think you have multiple DB request that could use asyncio, but most of the time they are dependent on each other. Almost all of the time a normal multithreaded Python server i…

Sure. As a general rule the general style of coding using in async-await approaches is primarily about one of two things

The first purpose is allowing more throughput at the expense of per request latency (Typically each request will take longer than with equivalent sync code).

The main scenario where an async version could potentially complete sooner than a sync version is when the the code is able to start multiple async tasks and then await then as a group. For example if your task needs to make 10 http requests, and make those requests sequentially like one would in sync code, it will be slower. If one starts all ten calls and then awaits the results, then you might be able to a speedup on this overall request.

Other main purpose is when working with a UI framework where there is a main thread, and certain operations can only occur on the main thread. Use of async/await pattern helps avoid accidentally blocking the main thread, which can kill application responsiveness. This is why the pattern is used in javascript, and was one of the headline scenarios when C# first introduced this pattern. (The alternative being other methods of asynchrony which typically include use of callbacks, which can make the code harder to develop or understand).

But basically, unless you have UI blocking problems, or are concerned about the number of requests per second you can handle, async-await patterns may be better avoided. It being even more costly in python than it is in some other languages does not really help.

Re: Python Asyncio

#150
post #134

Earlier quoted context omitted.

I am really not a fan of generators and yields for the same reason. But over time I've come to see it as ever-so-slightly more elegant syntax sugar for a class that maintains internal state to sequentially return specific values in response to a series of calls to a function.

The least they could have done is sugared it to something that isn't "def", like "gen" or "defgen"

Unless I'm misunderstanding your comment they do, it's `async def` to denote a coroutine.
Post reply on HN