-
-
Notifications
You must be signed in to change notification settings - Fork 2k
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
POC for hyperscan usage in UrlDispatcher #9907
base: master
Are you sure you want to change the base?
Conversation
for more information, see https://pre-commit.ci
CodSpeed Performance ReportMerging #9907 will degrade performances by 26.95%Comparing Summary
Benchmarks breakdown
|
aiohttp/web_urldispatcher.py
Outdated
@@ -1242,8 +1301,52 @@ def freeze(self) -> None: | |||
super().freeze() | |||
for resource in self._resources: | |||
resource.freeze() | |||
if HAS_HYPERSCAN: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haven't tested this yet but I expect it will break downstream Home Assistant since there is code there to register new routes as new integrations get loaded after startup. It's pretty clear the intent here was to not allow that after freeze but that's currently the downstream use case and hard to change it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point.
We can rebuild hypedscan db in UrlDispatcher.register_resource()
if the dispatcher was frozen.
I'm curious how Home Assistant works with route table on the fly.
If it adds new routes to started web server it should remove them at some point, isn't it?
Before moving forward, I'd like to add some benchmarks first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
About to go to the airport, but will dig up the Home Assistant code this weekend. It predates me though so will take a bit to figure it out.
We don't have any benchmarks for the url dispatcher. I'll look at downstream use cases and come up with some after I get back from travel next week.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you safe flight!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once I figure out how the downstream code works for adding routes at run time. I'll see if I can make that into meaningful test cases here as well so we don't break anything. AFAICT for a cursory review, routes are never removed when integrations are unloaded downstream.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Freezing and unfreezing on enter and exit will likely be too many rebuilds. ~297 routes get added at startup for Home Assistant. ~200 can be grouped together which would mean 200 rebuilds at startup
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another method could be to keep adding to the fallback dict as new routes are added, clear the hyperscan db when a route is added after freeze, schedule a timer handle to rebuild the db a few (60... maybe less) seconds later if one is not already scheduled
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
~200 can be grouped together which would mean 200 rebuilds at startup
If they're grouped together, shouldn't that be 1 rebuild?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clarify: Very few can be grouped together. The result is 200 groups of various sizes, mostly 1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Distribution of groupings looks something like 1, 9, 1, 7, 3, 3, 1, 1, 1, 1, 1 .....
However order is indeterminate as it relies on async task completion order
Co-authored-by: Sam Bull <[email protected]>
Managed to finish the benchmarks before boarding the flight. They should run if you update with master. Didn't have enough time to dig through downstream or write the tests yet though |
Thank you! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me. Seems we need a couple more tests for missing coverage though.
Just realized Hyperscan likely doesn't work on armv7l so maybe we need benchmarks for with Hyperscan not available as well. Maybe not though since armv7l is now slowly disappearing from the landscape now that the RPi shortage is over |
Perhaps parametrized benchmarks will help to measure both hyperscan and domestic versions. |
From the flame graph on cod speed it looks like test_resolve_gitapi_subapps is producing system routes (maybe 404s) |
Good finding, thanks! I guess an assertion will not hurt or significantly change timings. |
aiohttp is working on integrating hyperscan to improve url dispatch performance aio-libs/aiohttp#9907
https://pypi.org/project/hyperscan/ could speed up url dispatcher if available.
Fallback to the current implementation is supported if hyperscan compilation fails or not available.