Related to ORMs/queries/performance, I have found the following combination really good: * aiosql[0] to write raw SQL queries and having them available as python functions (discussed in [1]) * asyncpg[2] if you are using Postgres * Map asyncpg/aiosql results to Pydantic[3] models * FastAPI[4] Pydantic models become the "source of truth" inside the app, they are designed as a copy of the DB schema, then functions rece…
12 requests per second: A realistic look at Python web frameworks
171–180 of 239 posts
Re: 12 requests per second: A realistic look at Python web frameworks
#172C#/ASP.NET is the fastest web framework now: https://www.techempower.com/benchmarks/#section=test&runid=8... 7.000.000 requests per second Even GO can only achieve 4.500.000 million requests per secnod being a low-level language, in opposite to high-level C#.
( all those benchmarks are sort of useless anyway )
Re: 12 requests per second: A realistic look at Python web frameworks
#173Earlier quoted context omitted.
The programmer also already had the value in book.user_id but still chose to ask the ORM to fetch all of .user so they could get .id from there instead. And they might then afterward call .name on it as well, and there would be no further queries, because the ORM has already been asked to fetch all fields of .user - so it might in fact have been sensible to fetch all of .user if so. The query builder cannot know whet…
Perhaps i'm a bit odd, but when I'm going to lean on an ORM to do things I expect it to actually do them. I expect that foo.user_id does not exist, because that representation has been transformed into an object. foo.user.id should be the only viable reference to the id. foo.user.id should return the value it already knows, any other property access i would expect will do the equiv of `select * from ...` if the objec…
Or you can just consider user_id to be a reference pointer that is part of foo, while user.id is an attribute of user. Totally different things and I am glad that the distinction is there.
Re: 12 requests per second: A realistic look at Python web frameworks
#174Earlier quoted context omitted.
There is lots of truth to this. Some ORMs like Django perform joins in very unsuspecting ways. A simple example is, say, foreign keys. Trying to access the foreign key of an object by doing `book.user.id` does an additional query for the user table to get the ID. It's less known that the id is immediately available by just doing `book.user_id` instead. I've spent time optimising things like text searches down from 20…
The most insidious part about misusing ORMs is it's often not visible for a while. Modern DBMSs on modern hardware are crazy fast , so when you have only a few tens or hundreds of thousand rows in your table, those inefficient and pointless ORM queries are just not noticeable because you still get sub-second response times. As your database grows, the site begins to gets slower and slower, but it's hard to distinguis…
Re: 12 requests per second: A realistic look at Python web frameworks
#175Why is it so? I've got 100K requests per sec with PHP easily [1] [1] https://github.com/gotzmann/comet
Ok what's the secret sauce and downsides? Because as far as I know there's no way to cheat with PHP like C# did here:
https://github.com/TechEmpower/FrameworkBenchmarks/blob/mast...
Re: 12 requests per second: A realistic look at Python web frameworks
#176Earlier quoted context omitted.
That's a nice benefit of using async ORMs (not yet available in django), the db calls are explicit!
You can also commit to always use .values() in django. That makes it error out when you access non-prefetched entities
Re: 12 requests per second: A realistic look at Python web frameworks
#177My experience doing perf optimizations in real world systems with many many people writing code to the same app is a lot of inefficiencies happen due to over fetching data, inefficiencies caused by naively using the ORM without understanding the underlying cost of the query, and lack of actual profiling to find where the actual bottlenecks are (usually people writing dumb code without realizing it's expensive). Sure,…
There is lots of truth to this. Some ORMs like Django perform joins in very unsuspecting ways. A simple example is, say, foreign keys. Trying to access the foreign key of an object by doing `book.user.id` does an additional query for the user table to get the ID. It's less known that the id is immediately available by just doing `book.user_id` instead. I've spent time optimising things like text searches down from 20…
> Trying to access the foreign key of an object by doing `book.user.id` does an additional query for the user table to get the ID. It's less known that the id is immediately available by just doing `book.user_id` instead.
But that's not really unsuspecting. `book.user` is asking for the user table, `book.user_id` is not. Those two things are not identical even though they return the same value.
Re: 12 requests per second: A realistic look at Python web frameworks
#178My experience doing perf optimizations in real world systems with many many people writing code to the same app is a lot of inefficiencies happen due to over fetching data, inefficiencies caused by naively using the ORM without understanding the underlying cost of the query, and lack of actual profiling to find where the actual bottlenecks are (usually people writing dumb code without realizing it's expensive). Sure,…
I increasingly lean towards plain SQL over ORMs. It requires greater familiarity with SQL but I prefer that over greater familiarity with ORM-specific syntax that doesn’t translate across frameworks or languages. In addition, you can prototype new queries and profile existing queries in the database and copy-paste directly into your code.
So now my pattern is to use for example ActiveModel in Ruby for the models, but not ActiveRecord for the persistence part.
Re: 12 requests per second: A realistic look at Python web frameworks
#179Earlier quoted context omitted.
C# is only at number 3 in your list. Both Java and Rust are above it in the list. It's also a very "artificial" benchmark and real world code will give different results (if you have static content, just put it in a CDN and don't worry) Other benchmarks from the same site: - JSON Serialization: C# is number 34 - Single query: C# is number 23 - Fortunes: C# is number 7
It needs to be emphasized how artificial these benchmarks really are. Here is the source for the Fortunes C# benchmark: https://github.com/TechEmpower/FrameworkBenchmarks/blob/mast... There's no routing or templating, it just writes a bunch of strings. No one would build an actual web app this way. The only C# benchmarks that are remotely realistic are the mvc variants, starting with aspcore-mvc-ado-pg at number 79.
Routing is required, but generally the rules allow things to be "reasonable" and "acceptable", which lets all these weird implementations through.
Honestly, they should remove the "Implementation approach" column, because basically every implementation is marked as "realistic", making it meaningless.
Re: 12 requests per second: A realistic look at Python web frameworks
#180Why is it so? I've got 100K requests per sec with PHP easily [1] [1] https://github.com/gotzmann/comet
"Blazing fast with 100K HTTP requests per second and ~0.1 ms latency on commodity cloud hardware" Ok what's the secret sauce and downsides? Because as far as I know there's no way to cheat with PHP like C# did here: https://github.com/TechEmpower/FrameworkBenchmarks/blob/mast...
https://www.techempower.com/benchmarks/#section=data-r20&hw=...