Live data from Hacker News

Async Python is not faster

calpaterson.com

51–60 of 364 posts

Re: Async Python is not faster

#51
post #43

His async code creates a pool with only 10 max connections[1] (the default). Whereas his sync pool[2], with a flask app that has 16 workers, has significantly more database connections. I expect upping this number would have a positive effect on asyncio numbers because the only thing[3] this[4] is[5] measuring[6] is how many database connections you have, and is about as far from a realistic workload as you can get.…

Absolutely agree, sum to this the quality of the driver aiopg vs asyncpg...

Re: Async Python is not faster

#52
post #42

Earlier quoted context omitted.

alternatively, one can use gevent and get a transparent asyncio from a modified runtime - something that a high-level language should've provided out of the box.

Hiding awaitables from the language, sounds like against the zen (explicit better than implicit) For example, when someone access a descriptor in Django.. this could end being a query to the db (transparent) but dangerous. With asyncio you explicitly await something to return the execution to the event loop. At least for me sounds like a safer behaviour

> Hiding awaitables from the language, sounds like against the zen (explicit better than implicit)

Zen is not respected by explicit asyncio, just try to compose asyncio with iterators [1]

[1] https://stackoverflow.com/questions/42448664/async-generator...

This problem doesn't exist with gevent, and composability is a desired thing in any programming language. Python's asyncio fractioned the community that was previously doing implicit asyncio with sync interfaces, and the current state of API is not an example of composable primitives that follow the Zen of Python:

> Beautiful is better than ugly.

> Simple is better than complex.

> Readability counts.

> Special cases aren't special enough to break the rules.

Re: Async Python is not faster

#53

I use async for UI work, but don't have much of an opinion for servers. I suspect that the best async is that supported by the server OS, and the more efficiently a language/compiler/linker integrates with that, the better. JIT/interpreted languages introduce new dimensions that I have not experienced. I do have some prior art in optimizing libraries, though. In particular, image processing libraries in C++. My opini…

> profilers are more important than careful design.

> I have found that it's actually possible to have worse performance with threads, if you write in a blocking fashion

But isn't excessive blocking/synchronization not something the should already be tackled in your design instead of trying to rework it after the fact ?

I would expect profiling to mostly leads to micro-optimisations, eg combining or splitting the time a lock is taken, but when you're still designing you can look at avoiding as much need for synchronization as possible. eg: sharing data copy-on-write (not requiring locks as long as you have a reference) instead of having to lock the data when accessing it.

As another commenter says

> with asyncio we deploy a thread per worker (loop), and a worker per core. We also move cpu bound functions to a thread pool

you can't easily go from eg. thread-per-connection to a worker pool. that should have been caught during design

Re: Async Python is not faster

#54
PRO HACKERS HELPING PEOPLE +1302-648-5479 (text)

Is your partner keeping secrets of lately and you want to know why? you feel your partner is cheating on you? Do you or someone you know have a police or court case and want the case CLEARED and forgotten by us hacking into FBI or government server and wiping off HISTORY of its existence? Did someone steal your money and you want the person found and your money recovered? Do you feel somebody is spying on you or bugging you and you want the person out of your way or exposed? Did you lost or forget password to your Facebook,Instagram,twitter,Gmail,Yahoomail,Hotmail etc and want them recovered? Do you wish to spy on somebody's computer or phone? Did you loose contact with someone(family member or old friend) and wish to know where they are and how to locate them for you all to reconnect? Did you lose a pet(dog,cat etc)and want them found? You're welcome to our world. We're professional hackers and can invade devices(phones, emails,whasapp,text messages,Facebook,Instagram etc),hack out information you need and forward to you. Then you will stay happy.

+13026485479 (texts only) globalhacker1986@gmail.com

Re: Async Python is not faster

#55

> 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…

alternatively, one can use gevent and get a transparent asyncio from a modified runtime - something that a high-level language should've provided out of the box.

What does gevent do - give Python something similar to Goroutines?

Re: Async Python is not faster

#56
post #43

His async code creates a pool with only 10 max connections[1] (the default). Whereas his sync pool[2], with a flask app that has 16 workers, has significantly more database connections. I expect upping this number would have a positive effect on asyncio numbers because the only thing[3] this[4] is[5] measuring[6] is how many database connections you have, and is about as far from a realistic workload as you can get.…

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, if you're maxing out your database with sync code then async isn't going to make it magically go faster.

Re: Async Python is not faster

#58
post #53

I use async for UI work, but don't have much of an opinion for servers. I suspect that the best async is that supported by the server OS, and the more efficiently a language/compiler/linker integrates with that, the better. JIT/interpreted languages introduce new dimensions that I have not experienced. I do have some prior art in optimizing libraries, though. In particular, image processing libraries in C++. My opini…

> profilers are more important than careful design. > I have found that it's actually possible to have worse performance with threads, if you write in a blocking fashion But isn't excessive blocking/synchronization not something the should already be tackled in your design instead of trying to rework it after the fact ? I would expect profiling to mostly leads to micro-optimisations, eg combining or splitting the tim…

> But isn't excessive blocking/synchronization not something the should already be tackled in your design instead of trying to rework it after the fact ?

Yes and no. Again, I have not profiled or optimized servers or interpreted/JIT languages, so I bet there's a new ruleset.

Blocking can come from unexpected places. For example, if we use dependencies, then we don't have much control over the resources accessed by the dependency.

Sometimes, these dependencies are the OS or standard library. We would sometimes have to choose alternate system calls, as the ones we initially chose caused issues which were not exposed until the profile was run.

In my experience, the killer for us was often cache-breaking. Things like the length of the data in a variable could determine whether or not it was bounced from a register or low-level cache, and the impact could be astounding. This could lead to remedies like applying a visitor to break up a [supposedly] inconsequential temp buffer into cache-friendly bites.

Also, we sometimes had to recombine work that we had sent to threads, because that caused cache hits.

Unit testing could be useless. For example, the test images that we often used were the classic "Photo Test Diorama" variety, with a bunch of stuff crammed onto a well-lit table, with a few targets.

Then, we would run an image from a pro shooter, with a Western prairie skyline, and the lengths of some of the convolution target blocks would be different. This could sometimes cause a cache-hit, with a demotion of a buffer. This taught us to use a large pool of test images, which was sometimes quite difficult. In some cases, we actually had to use synthesized images.

Since we were working on image processing software, we were already doing this in other work, but we learned to do it in the optimization work, too.

When my team was working on C++ optimization, we had a team from Intel come in and profile our apps.

It was pretty humbling.

Re: Async Python is not faster

#59
post #43

His async code creates a pool with only 10 max connections[1] (the default). Whereas his sync pool[2], with a flask app that has 16 workers, has significantly more database connections. I expect upping this number would have a positive effect on asyncio numbers because the only thing[3] this[4] is[5] measuring[6] is how many database connections you have, and is about as far from a realistic workload as you can get.…

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 lot, and pretty much all CPU time was still spent in Python.

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.

I think making a database query and responding with JSON is a very realistic workload. I've coded that up many times. Changing it to make requests to other things (mimicking a microservice architecture) is also interesting and if you did that I'd be interested to read your write up.

Re: Async Python is not faster

#60
post #55

Earlier quoted context omitted.

alternatively, one can use gevent and get a transparent asyncio from a modified runtime - something that a high-level language should've provided out of the box.

What does gevent do - give Python something similar to Goroutines?

yes, pretty much, with a few specifics - https://sdiehl.github.io/gevent-tutorial/#greenlets
Post reply on HN