-
-
Notifications
You must be signed in to change notification settings - Fork 829
-
-
Notifications
You must be signed in to change notification settings - Fork 829
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
httpx.AsyncClient
has much worse performance than aiohttp.ClientSession
with concurrent requests
#3215
Comments
Found some related discussions: Opening a proper issue is warranted to get better visibility for this. So the issue is easier to find for others. In its current state |
Oh, interesting. There's some places I can think of where we might want to be digging into here...
Possibly points of interest here...
Also, the tracing support in both aiohttp and in httpx are likely to be extremely valuable to us here. |
Thank you for the good points!
My original benchmark hit AWS S3. There I got very similar results where |
Okay, thanks. Was that also testing small |
Yes pretty much, GET of a file with size of a couple KB. In the real system the sizes ofcourse vary alot. |
@tomchristie you were right, this is the issue ^! When I just do a simple patch into |
There is another hot spot in The logic in connection pool is quite heavy as it rechecks all of the connections every time requests are assigned to the connectors. It might be possible to skip the Probably it would be good idea to add some performance tests to httpx/httpcore CI. |
I can probably help with a PR if you give me pointers about how to proceed :) I could eg replace the synchronization primitives to use the native asyncio. |
See encode/httpcore#344, #1511, and encode/httpcore#345 for where/why we switched over to anyio.
A good first pass onto this would be to add an You might want to work from the last version that had an Docs... https://www.encode.io/httpcore/network-backends/ Other context...
|
Thanks @tomchristie What about this case I pointed:
There switching network backend won't help as the lock is not defined by the network implementation. The lock implementation is a global one. Should we just change the synchronization to use asyncio? |
I'm able to push the performance of Previously (in You can see the benchmark here. Here are the changes. There are 3 things required to improve the performance to get it as fast as
I'm happy to open a PR from these. What do you think @tomchristie? |
@MarkusSintonen - Nice one. Let's work through those as individual PRs. Is it worth submitting a PR where we add a |
I think it would be beneficial to have benchmark run in CI so we would see the difference. Previously I have contributed to Pydantic and they use codspeed. That outputs benchmark diffs to PR when the benchmarked behaviour changes. It should be free for open-source projects. |
That's an interesting idea. I'd clearly be in agreement with adding a |
@tomchristie I have now opened the 2 fix PRs:
Maybe Ill open the network backend addition after these as its the most complex one. |
Maybe you can refer to the implementation of aiohttp |
Isn't usage of http.CookieJar a part of the problem? Line 1020 in db9072f
|
@rafalkrupinski I haven't run benchmarks when requests/responses uses cookies but atleast it doesnt cause performance issues in general. I run similar benchmarks from
(Waiting for review from @tomchristie) |
TBH I'm surprised by httpx ditching anyio. Sure anyio comes with performance overhead, but this is breaking compatibility with Trio. |
I'm not aware of it ditching it completely. It will still support using it, it's just optional. Trio will be also supported by httpcore. |
These are really cool speed-ups. Can't wait for httpx to overtake aiohttp ;) |
Since the benchmark seems to be using http I think below is also a related issue where creation of ssl context in httpx had some overhead compared to aiohttp. Ref : #838 |
Hi, any movements on the PRs? We're having to use both aiohttp and httpx in our project because of this reason, whereas we'd like to only have 1 set of API. |
I use aiohttp to encapsulate a chain call method, which I personally feel is pretty good. url = "https://juejin.cn/"
resp = await AsyncHttpClient().get(url).execute()
# json_data = await AsyncHttpClient().get(url).json()
text_data = await AsyncHttpClient(new_session=True).get(url).text()
byte_data = await AsyncHttpClient().get(url).bytes() example:https://github.com/HuiDBK/py-tools/blob/master/demo/connections/http_client_demo.py |
There seems to be some performance issues in
httpx
(0.27.0) as it has much worse performance thanaiohttp
(3.9.4) with concurrently running requests (in python 3.12). The following benchmark shows how running 20 requests concurrently is over 10x slower withhttpx
compared toaiohttp
. The benchmark has very basichttpx
usage for doing multiple GET requests with limited concurrency. The script outputs a figure showing how duration of each GET request has a huge duration variance withhttpx
.I found the following issue but seems its not related as the workaround doesnt make a difference here #838 (comment)
The text was updated successfully, but these errors were encountered: