11"""codspeed benchmarks for the web file responses."""
22
33import asyncio
4+ import os
45import pathlib
56import ssl
67from collections .abc import Awaitable , Callable , Iterator
@@ -77,26 +78,48 @@ def conn_type(
7778 return ConnectionType (s_kwargs = {}, c_kwargs = {})
7879
7980
81+ @dataclass (frozen = True )
82+ class BenchmarkFile :
83+ path : pathlib .Path
84+ response_count : int
85+
86+
87+ @pytest .fixture (
88+ params = ((10 * 1024 , 100 ), (1024 * 1024 , 10 )),
89+ ids = ("small" , "large" ),
90+ )
91+ def benchmark_file (
92+ request : pytest .FixtureRequest , tmp_path : pathlib .Path
93+ ) -> BenchmarkFile :
94+ size , response_count = request .param
95+ filepath = tmp_path / "sample.txt"
96+ filepath .touch ()
97+ os .truncate (filepath , size )
98+ return BenchmarkFile (filepath , response_count )
99+
100+
80101def test_simple_web_file_response (
81102 event_loop : asyncio .AbstractEventLoop ,
82103 aiohttp_client_sync : AiohttpClient ,
83104 benchmark : BenchmarkFixture ,
84105 conn_type : ConnectionType ,
106+ benchmark_file : BenchmarkFile ,
85107) -> None :
86- """Benchmark creating 100 simple web.FileResponse."""
87- response_count = 100
88- filepath = pathlib .Path (__file__ ).parent / "sample.txt"
108+ """Benchmark simple web.FileResponse."""
89109
90110 async def handler (request : web .Request ) -> web .FileResponse :
91- return web .FileResponse (path = filepath )
111+ return web .FileResponse (path = benchmark_file . path )
92112
93113 app = web .Application ()
94114 app .router .add_route ("GET" , "/" , handler )
95115
96116 async def run_file_response_benchmark () -> None :
97117 client = await aiohttp_client_sync (app , server_kwargs = conn_type .s_kwargs )
98- for _ in range (response_count ):
99- await client .get ("/" , ** conn_type .c_kwargs )
118+ for _ in range (benchmark_file .response_count ):
119+ response = await client .get ("/" , ** conn_type .c_kwargs )
120+ # Consume response.
121+ # Large responses may leave transport unclosed on at least python 3.10.
122+ await response .read ()
100123 await client .close ()
101124
102125 @benchmark
@@ -109,24 +132,24 @@ def test_simple_web_file_sendfile_fallback_response(
109132 aiohttp_client_sync : AiohttpClient ,
110133 benchmark : BenchmarkFixture ,
111134 conn_type : ConnectionType ,
135+ benchmark_file : BenchmarkFile ,
112136) -> None :
113- """Benchmark creating 100 simple web.FileResponse without sendfile."""
114- response_count = 100
115- filepath = pathlib .Path (__file__ ).parent / "sample.txt"
137+ """Benchmark simple web.FileResponse without sendfile."""
116138
117139 async def handler (request : web .Request ) -> web .FileResponse :
118140 transport = request .transport
119141 assert transport is not None
120142 transport ._sendfile_compatible = False # type: ignore[attr-defined]
121- return web .FileResponse (path = filepath )
143+ return web .FileResponse (path = benchmark_file . path )
122144
123145 app = web .Application ()
124146 app .router .add_route ("GET" , "/" , handler )
125147
126148 async def run_file_response_benchmark () -> None :
127149 client = await aiohttp_client_sync (app , server_kwargs = conn_type .s_kwargs )
128- for _ in range (response_count ):
129- await client .get ("/" , ** conn_type .c_kwargs )
150+ for _ in range (benchmark_file .response_count ):
151+ response = await client .get ("/" , ** conn_type .c_kwargs )
152+ await response .read ()
130153 await client .close ()
131154
132155 @benchmark
0 commit comments