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
[cheroot==8.1.0 regression] Significant performance drop #305
Comments
Hey @mar10, thanks for the heads up! v8.1.0 introduced a number of functional regressions that are got some fixes in v8.3.0 and v8.4.0 so please also test with these. It was a result of refactoring the connection management to decouple keep-alive TCP connections from HTTP requests. So I'd say that you should also check whether your tool reuses the connections or creates new ones of each HTTP request. |
Hi Sviatoslav, I already tested with 8.3.1 and 8.4.0 with same results. stressor uses the requests library with sessions, which should support keep-alive, but I can double check. However, even if it did not reuse connections, would the refactoring explain that cheroot now slows down to 25% (for my specific benchmark)? |
Hm... I think you use the same session for all the requests meaning that they all are processed sequentially because they come one after another over the wire in the same TCP connection. HTTP/1.1 doesn't have built-in parallelism, unlike HTTP/2 that uses streams within the same connection. Try checking that it does use just one connection (using tcpdump/wireshark, I guess). Also try make stressor creat a number of sessions and load-balance the queries. Plus try stress-testing with some other tool like ab/wrk2/locust. |
Stressor spawns one thread for every virtual user. Cheroot 8.0Executed 10,163 activities in 10,163 sequences, using 1 parallel sessions. => 338.8 requests per sec/user Cheroot 8.4Executed 292 activities in 292 sequences, using 1 parallel sessions. => 9.7 requests per sec/user It may sound silly, but it looks like someone introduced a |
Weird. This clearly needs profiling. What are the thread num settings in your setup? |
@mar10 mind record a flame graph using https://github.com/benfred/py-spy? |
numthreads is set to 50. py-spy looks interesting, I will try it out if I find time. However, I searched for "0.1" and found that try:
for fno in socket_dict:
self._selector.register(fno, selectors.EVENT_READ)
rlist = [
key.fd for key, _event
in self._selector.select(timeout=0.1)
]
except OSError:
... I patched the timeout value and ran the benchmarks again timeout=0.1 (original) timeout=0.05 timeout=0.02 timeout=0.01 Smaller values don't seem to improve the performance. |
This change addresses a significant performance regression that was introduced in v8.1.0 (see #305), sort-term. It makes the sockets select timeout shorter to reduce the duration of each tick in the new connection processing loop. The proper fix is yet to be created per #308 (comment)
Extracting what @liamstask posted in the PR:
(Originally posted by @liamstask in #308 (comment)) |
8.4.2 fixed it for me, thanks 8.4.1: 8.4.2: |
@liamstask does #309 fix this? |
β I'm submitting a ...
π Describe the bug. What is the current behavior?
This more a note than a bug report:
I run some benchmark against my project (WsgiDAV] and found that there is a drastical drop in performance between cheroot versions 8.0.0 and 8.1.0.
The test uses a homegrown tool (stressor) that runs a test script (see here):
Benchmarks show 11k activities per 30 seconds until v8.0.
Starting with cheroot 8.1 this drops to 2.9k activities per 30 sec.
I also tried with gevent as backend, and it delivered 12.4k activities.
Please note that these results may be due to poor implementation on my tools, but all I changed was WSGI server behind WsgiDAV, so I thought I let you know.
π‘ To Reproduce
See https://github.com/mar10/wsgidav/blob/master/tests/stressor/results.md
If you are interested, I can provide more details.
Cheers
Martin
The text was updated successfully, but these errors were encountered: