News for hackers. Stuff that matters.
Re:Show HN: 1M rows/s from Postgres to Python by zzzeek on Thursday August 04, 2016 @06:15PM (#12228850)
> This simply isn't true for all use cases.

Everytime I talk about my blog post, I am super careful to qualify: in this case, "usually has little to do w/ speed" and other qualifications. The blog post as well. But everytime, I get a response, "but that's not always TRUE!" We agree. It is not always true. But it is usually true :).

> If you have to manage 100-1000s of connections

Which I said, usually you are not. Postgresql connections are expensive. You do not want 100s-1000s.

> some of each can be long-living sessions such as websockets

you use websockets to talk to your Postgresql database? Where did I say I was talking about HTTP web services ?

> However GIL will make things really slow under load.

not IO load with a hundred threads or so. Thousands, sure. Otherwise no.

Re:Show HN: 1M rows/s from Postgres to Python by RedCrowbar on Thursday August 04, 2016 @06:38PM (#12228951)
> Everytime I talk about my blog post, I am super careful to qualify: in this case, "usually has little to do w/ speed" and other qualifications. The blog post as well.

I created an asyncpg suite for your bigdata benchmark (https://bitbucket.org/zzzeek/bigdata). Here are the results obtained from running it on my laptop against local PostgreSQL 9.5.

300 connections:

    Python3.5.2 threads -- avg 9798.16 recs/sec
    Python3.5.2 gevent -- avg 9677.84 recs/sec
    Python3.5.2 uvloop/asyncpg -- avg 11558.24 r/sec
The modified suite is here: https://github.com/elprans/bigdata
Re:Show HN: 1M rows/s from Postgres to Python by zzzeek on Thursday August 04, 2016 @06:53PM (#12229025)
that's great, you've written a very fast driver. My benchmarks are comparing psycopg2 to itself, under threads / gevent vs. asyncio, to show that asyncio is inherently slower. It follows that if you wrote your driver and all of its protocol improvements into a traditional blocking model, it would also be much faster. You've written something so fast that it overcomes the latency of asyncio (this whole thread is a huge plug for your driver, btw).

It's not that the latency of asyncio is really that big of a deal. The point I try to make is, asyncio != speed. For databases, 95% of the time, it means, a little less speed. Not a big deal, but if you aren't into writing explicit context switching directives throughout 100% of your code when the OS does it for you just fine, it isn't worth it, unless you are in the zone of thousands of arbitrarily performing connections, which is really more of an incoming client connection thing, not usually a database thing.

Re:Show HN: 1M rows/s from Postgres to Python by RedCrowbar on Thursday August 04, 2016 @07:08PM (#12229087)
> that's great, you've written a very fast driver. My benchmarks are comparing psycopg2 to itself,

OK, I ran the asyncio suite (with uvloop event loop):

Python3.5.2 asyncio+psycopg+uvloop -- avg 8356.84 recs/sec

Really not that slower. There is also an important detail that you forget to mention: the threaded benchmark uses notably more CPU time (about 30% more).

Re:Show HN: 1M rows/s from Postgres to Python by 1st1 on Thursday August 04, 2016 @06:20PM (#12228869)
>> If you have to manage 100-1000s of connections

> Which I said, usually you are not. Postgresql connections are expensive. You do not want 100s-1000s.

I was talking about a micro-service that has to support a lot of connections and work with a DB.

>> some of each can be long-living sessions such as websockets

> you use websockets to talk to your Postgresql database? Where did I say I was talking about HTTP web services ?

So you were talking about programs that don't communicate with the outside world except to a DB?

Re:Show HN: 1M rows/s from Postgres to Python by zzzeek on Thursday August 04, 2016 @06:24PM (#12228884)
If you write a program that has thousands of persistent websockets open, you do not want all those thousands of connections to each have their own, persistent, long lived database transaction. You will not like your process listing nor will you be happy about the amount of table and row locking going on. Transactions and connection scope should be short lived, and if you're using a connection pool, you definitely are going for that. As my blog post stated, you'd use a thread pool for the database access part, given that the http-facing side is async.
Re:Show HN: 1M rows/s from Postgres to Python by zzzeek on Thursday August 04, 2016 @06:31PM (#12228923)
> Mike, I've never suggested to have a DB connection per HTTP request.

right, so my suggestion is, keep the DB code in a thread pool. So you can use the async for your 1000-client frontend and not force it into the DB layer where it makes things much more complicated (or what I do, just use gevent :) ).

Re:Show HN: 1M rows/s from Postgres to Python by allendoerfer on Thursday August 04, 2016 @06:38PM (#12228953)
Sorry to interrupt: You two can click on the timestamp to answer your posts. Please continue, we are listening carefully.

And since I am already here @1st1: How hard would it be to create a synchronous version of your adapter?

Re:Show HN: 1M rows/s from Postgres to Python by 1st1 on Thursday August 04, 2016 @06:49PM (#12229001)
A lot of code in asyncpg is datatypes parsers, buffer abstractions, API facade and other IO independent things. So good news is that it would be possible to reuse a lot of code.

Protocol is implemented in two layers -- the base layer is IO and framework independent. The higher level is designed for asyncio.

Long story short, it's possible to add a synchronous version, but it still will require a lot of work. The API will also have to be split in two.

Re:Show HN: 1M rows/s from Postgres to Python by zzzeek on Thursday August 04, 2016 @07:24PM (#12229144)
It's possible to make a really nice async sqlalchemy core too, and even some of the ORM. huge amount of work, i started on just the connection pool. Would be nice but require all its own test coverage and everything. If i was the CEO of sqlalchemy inc, it would have been done. But that's not where my salary comes from :)
Re:Show HN: 1M rows/s from Postgres to Python by allendoerfer on Thursday August 04, 2016 @08:10PM (#12229304)
SQLAlchemy is clearly one of the best ORMs (maybe there is something in Java-land that I don't know). It is beyond me how you are not guilted by cash getting thrown in your direction into making this your job.

Well, I like what bountysource.com and others are doing, maybe we will get there.

Re:Show HN: 1M rows/s from Postgres to Python by infinite8s on Friday August 05, 2016 @10:25AM (#12232525)
It's the tragedy of open source. See - https://news.ycombinator.com/item?id=10905845
Re:Show HN: 1M rows/s from Postgres to Python by allendoerfer on Thursday August 04, 2016 @07:04PM (#12229074)
I think you should open a bounty for it. As questions like "Can I use this with Django/SQLAlchemy/…?" showed, people love drop-in replacements that speed up their code, especially when it is at a low level like this.

Do not want to sound ungrateful, though. Thank you for your work also on you other contributions. Would definitely use this when applicable. Are more performance related projects like this and uvloop planned?

Re:Show HN: 1M rows/s from Postgres to Python by 1st1 on Thursday August 04, 2016 @07:18PM (#12229129)
> I think you should open a bounty for it. As questions like "Can I use this with Django/SQLAlchemy/…?" showed, people love drop-in replacements that speed up their code, especially when it is at a low level like this.

We'll consider doing that. We have to keep in mind that supporting two IO modes will add a lot of maintenance overhead. Anyways, we can certainly continue the discussion on GH, and maybe we can find a champion to do the heavy-lifting.

> Do not want to sound ungrateful, though. Thank you for your work also on you other contributions. Would definitely use this when applicable. Are more performance related projects like this and uvloop planned?

Thank you.

Right now most of our resources are consumed by getting EdgeDB alpha out as soon as possible. We also have plans to create a micro web framework based on httptools and few other exciting ideas. Stay tuned :)

Also check out PEP 525 -- another cool thing we're trying to make happen in Python 3.6.

Re:Show HN: 1M rows/s from Postgres to Python by 1st1 on Thursday August 04, 2016 @06:41PM (#12228967)
> right, so my suggestion is, keep the DB code in a thread pool. So you can use the async for your 1000-client frontend and not force it into the DB layer where it makes things much more complicated (or what I do, just use gevent :) ).

Looks like a totally valid suggestion for folks who write async code and want to continue to use SQL Alchemy.

However, if you don't use SQL Alchemy (or another ORM) and just want to work with the DB directly in an async/await code base, having a threadpool will only needlessly complicate things.

Re:Show HN: 1M rows/s from Postgres to Python by 1st1 on Thursday August 04, 2016 @06:26PM (#12228900)
> If you write a program that has thousands of persistent websockets open, you do not want all those thousands of connections to each have their own, persistent, long lived database transaction. [..]

Mike, I've never suggested to have a DB connection per HTTP request. Please re-read my other comment in this thread.