Earlier quoted context omitted.
He only has 4 CPUs. I doubt rising the worker count is going to help the async situation. From my experience it’s really hard to make async outperform sync when databases are involved because the async layer adds so much overhead. Only when you are completely io bound with lots of connections does async outperform sync in python.
> From my experience it’s really hard to make async outperform sync when databases are involved because the async layer adds so much overhead Highly disagree as the database is just another IO connection to a server, which is asyncio bread and butter. Being able to stream data from longer running queries without buffering and whilst serving other requests (and making other queries) is really quite powerful. But yeah,…
Async Python is not faster
131–140 of 364 posts
Re: Async Python is not faster
#132Earlier quoted context omitted.
Hi - as mentioned in the article all connections went through pgbouncer (limited to 20) and I was careful to ensure that all configurations saturated the CPU so I'm pretty confident they were not waiting on connections to open. Opening a connection from pgbouncer over a unix socket is very fast indeed - my guess is perhaps a couple of orders of magnitude faster than without it. 20 connections divided by 4 CPUs is a l…
>Sidenote here: one thing I found but didn't mention (the reason I put in the pooling, both in Python and pgbouncer) is that otherwise, under load, the async implementions would flood postgres with open connections and everything would just break down. Doesn't this prove that async is waiting for connections when you put a limit on it? The only way async wins is if it is free to hit the db whenever it needs to.
Re: Async Python is not faster
#133Earlier quoted context omitted.
> but that bit of overhead is probably a lot less than the 3 billion cpu cycles you'll waste waiting 1000ms for an external service. You are not waiting for that 1000ms, and you haven't been for 35 years since the first os's starting feature preemptive multitasking. When you wait on a socket, the OS will remove you from the CPU and place someone who is not waiting. When data is ready, you are placed back. You aren't…
> You are not waiting for that 1000ms, and you haven't been for 35 years since the first os's starting feature preemptive multitasking. 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 multithrea…
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.
Re: Async Python is not faster
#134> Function colouring is a big problem in Python Not when you know how to call sync functions from async functions and vice versa. An sync function can call an async function via: loop = asyncio.new_event_loop() result = loop.run_until_complete(asyncio.ensure_future(red(x))) A async function can call a sync function via: loop = asyncio.get_event_loop() result = await loop.run_in_executor(None, blue, x) Where red and b…
result = asyncio.run(red(x))
Re: Async Python is not faster
#135How is this result surprising? The point of coroutines isn't to make your code execute faster, it's to prevent your process sitting idle while it waits for I/O. When you're dealing with external REST APIs that take multiple seconds to respond, then the async version is substantially "faster" because your process can get some other useful work done while it's waiting. Obviously the async framework introduces some over…
> When you're dealing with external REST APIs that take multiple seconds to respond, then the async version is substantially "faster" because your process can get some other useful work done while it's waiting. Obviously the async framework introduces some overhead, but that bit of overhead is probably a lot less than the 3 billion cpu cycles you'll waste waiting 1000ms for an external service. but threads get you th…
That is not true, at least not in general, the whole point of using continuations for async I/O is to avoid the overhead of using threads, the scheduler overhead, the cost of saving and restoring the processor state when switching tasks, the per thread stack space, and so on.
Re: Async Python is not faster
#136Earlier quoted context omitted.
You perfectly illustrated why this is a problem. Calling functions from one side to the other involves ceremony. Ceremony adds cognitive overhead and decreases readability.
I've written Python functions that "call" another function either async or not depending on how the function inspects. For instance, imagine a "maybe_await" method that just calls sync if is synchronous or otherwise awaits.
result = yourfunc()
if inspect.iscoroutine(result):
result = asyncio.run(result)
If I have code like that, it's at one place per library, didn't need to encapsulate it in a maybe_await function.Re: Async Python is not faster
#137> Function colouring is a big problem in Python Not when you know how to call sync functions from async functions and vice versa. An sync function can call an async function via: loop = asyncio.new_event_loop() result = loop.run_until_complete(asyncio.ensure_future(red(x))) A async function can call a sync function via: loop = asyncio.get_event_loop() result = await loop.run_in_executor(None, blue, x) Where red and b…
You perfectly illustrated why this is a problem. Calling functions from one side to the other involves ceremony. Ceremony adds cognitive overhead and decreases readability.
result = asyncio.run(red(x))
That's calling async function red from non-async code.Not seeing any particular readability issue with that usage neither. If you don't call asyncio.run or await on the result of an async function call, then you get a coroutine for result.
Re: Async Python is not faster
#138I am SUPER happy someone else is finally looking at this. It is long past time that the reflexive use of asycnio or systems like gevent/eventlet for no other reason than "hand-wavy SPEED" come to an end. That web applications that literally serve just one user at at time are built in Tornado for "speed". (my example for this is the otherwise excellent SnakeViz: https://jiffyclub.github.io/snakeviz/ which IMO should h…
It's a difficult myth to dispel and I think the situation in terms of public mindshare is much worse now than it was in 2015. Some very silly claims from the async crowd now have basically widespread credence. I think one of the root causes is that people are sometimes very woolly about how multi-processing works. One of the others is that I think it's easy to make the conceptual mistake of 1 sync workers = 1 async worker and do a comparison that way
One of my worries is that right now it feels like everything in Python is being rewritten in asyncio and the balkanisation of the community could well be more problematic than 2 vs 3.
Re: Async Python is not faster
#139Earlier quoted context omitted.
... I never meant to imply that performance was the reason for the switch. We've had a track record of technologies which: 1) Automated things (reliving programmers from thinking about stuff) 2) Were expected to make stuff slower 3) In reality, sped stuff up, at least in the typical case, once algorithms got smart That's true for interpreted/dynamic languages, automated memory management/garbage collection, managed r…
> That's true for interpreted/dynamic languages, automated memory management/garbage collection, managed runtimes of different sorts, high-level descriptive languages like SQL, etc. Of the things you mention, I agree on SQL, and "managed runtimes" is generic enough that I cannot really judge. I'm thoughroghly unconvinced about the rest being faster than the alternatives (and that's why you don't see many SQL servers…
There's a big difference between normal code and hand-tweaked optimized code. SQL servers are extremely tuned, performant code. Short of hand-written assembly tuned to the metal, little beats hand-optimized C.
I was talking about normal apps. If I'm writing a generic database-backed web app, a machine learning system, or a video game. Most of those, when written in C, are finished once they work, or at the very most have some very basic, minimal profiling / optimization.
For most code:
1) Expressing that in a high-level system will typically give better performance than if I write it in a low-level system for V0, the stage I first get to working code (before I've profiled or optimized much). At this stage, the automated systems do better than most programmers do, at least without incredible time investments.
2) I'll be able to do algorithmic optimizations much more quickly in a high-level programming language than in C. With a reasonably time-bounded investment in time, my high-level code tends to be faster than my low-level code -- I'll have the big-O level optimizations finished in a fraction of the time, so I can do more of them.
3) My low-level code gets to be faster once I get into a very high level of hand-optimization and analysis.
Or in other words, I can design memory management better than the automated stuff, but my get-the-stuff-working level of memory management is no longer better than the automated stuff. I can design data structures and algorithms better than PostgreSQL specific to my use case, but those won't be the first ones I write (and in most cases, they'll be good enough, so I won't bother improving them). Etc.
Re: Async Python is not faster
#140I find it interesting that all the talk here is about performance, and nobody has mentioned any benefits of Async Python when performance isn't an issue. I use trio/asyncio to more easily write correct complex concurrent code when performance doesn't matter. See "The Problem with Threads"[1]. For this use case, Async Python probably still isn't faster, but that doesn't matter. Let's not throw out the baby with the ba…
I love asyncio for writing mixed initiative "servers". For instance, I have an asyncio "server" that accepts websocket connections on one side, waits on an AQMP queue, proxies requests and mediates for the HEOS smart speaker API, Phillips Hue, U.S. Weather Service, etc. This is great for react or vue front end applications which get their state updated when things happen in the outside world (e.g. somebody else start…