From 20b7a7b0c2463a3ae02073e13704ce4c7b478f30 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 22:09:30 +0100 Subject: [PATCH] [PR #9954/be31bed2 backport][3.11] Add url dispatcher benchmark for resolving root route when exists many plain routes in the subtree (#9959) **This is a backport of PR #9954 as merged into master (be31bed20210b6d7380aed8702a17994ea6a2d59).** Yet another benchmark. There is a tree: ``` / /api /api/server /api/server/dispatch /api/server/dispatch/123 /api/server/dispatch/123/update ``` The benchmark resolves the root route `/`. If the search starts from checking deep-most resource it cold be suboptimal. Co-authored-by: Andrew Svetlov --- tests/test_benchmarks_web_urldispatcher.py | 38 ++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tests/test_benchmarks_web_urldispatcher.py b/tests/test_benchmarks_web_urldispatcher.py index 033e2543a73..5d151d984af 100644 --- a/tests/test_benchmarks_web_urldispatcher.py +++ b/tests/test_benchmarks_web_urldispatcher.py @@ -69,6 +69,44 @@ def _run() -> None: loop.run_until_complete(run_url_dispatcher_benchmark()) +def test_resolve_root_route_with_many_fixed_routes( + loop: asyncio.AbstractEventLoop, + benchmark: BenchmarkFixture, +) -> None: + """Resolve top level PlainResources route 100 times.""" + resolve_count = 100 + + async def handler(request: web.Request) -> NoReturn: + assert False + + app = web.Application() + app.router.add_route("GET", "/", handler) + for count in range(250): + app.router.add_route("GET", f"/api/server/dispatch/{count}/update", handler) + app.router.add_route("GET", f"/api/server/dispatch/{count}", handler) + app.router.add_route("GET", "/api/server/dispatch", handler) + app.router.add_route("GET", "/api/server", handler) + app.router.add_route("GET", "/api", handler) + app.freeze() + router = app.router + request = _mock_request(method="GET", path="/") + + async def run_url_dispatcher_benchmark() -> Optional[web.UrlMappingMatchInfo]: + ret = None + for _ in range(resolve_count): + ret = await router.resolve(request) + + return ret + + ret = loop.run_until_complete(run_url_dispatcher_benchmark()) + assert ret is not None + assert ret.get_info()["path"] == "/", ret.get_info() + + @benchmark + def _run() -> None: + loop.run_until_complete(run_url_dispatcher_benchmark()) + + def test_resolve_static_root_route( loop: asyncio.AbstractEventLoop, benchmark: BenchmarkFixture,