aiohttp 文件响应基准测试升级:按 small/large 文件大小参数化 `web.FileResponse` 性能评估
后端Web框架WebSocket【免费下载链接】aiohttpAsynchronous HTTP client/server framework for asyncio and Python项目地址https://gitcode.com/gh_mirrors/ai/aiohttp点击查看免费下载本篇技术指南围绕 aiohttp 仓库变更记录 CHANGES/12913.misc.rst 展开它记录了 aiohttp 将test_simple_web_file_response与test_simple_web_file_response_fallback两个基准测试按文件大小small / large进行参数化的改动。读者读完本篇后将能理解 aiohttp 基准测试的编写方式、web.FileResponse的 sendfile 与 fallback 两条发送路径的底层差异以及为什么“只测小文件”会让基准测试失真。一、变更背景为什么基准测试不能只测一个文件大小改动之前aiohttp 的web.FileResponse基准测试只使用一个约 11 KB 的小文件即仓库中的 tests/sample.txt实际大小 11358 字节来评估文件响应性能。单一样本的基准测试存在明显的盲区sendfile 路径与 fallback 路径的差异大文件更依赖底层零拷贝sendfile系统调用的吞吐能力而小文件更多体现响应对象创建与头部处理的开销只测小文件无法反映大文件的吞吐瓶颈。内存与分块行为不同fallback 路径按chunk_size分块读取并写入文件越大分块次数越多行为差异越显著。连接与传输层状态不同大响应可能让传输层在 Python 3.10 上出现未正常关闭的情况测试源码中专门有注释说明这一点。因此这次变更由贡献者tarasko提交编号 12913把两个核心基准测试参数化为 small10 KB与 large1 MB两种文件规模让性能数据覆盖两种典型场景。二、参数化实现small 与 large 两档文件规模改动落在基准测试文件 tests/test_benchmarks_web_fileresponse.py 中。核心是新增了一个按参数化生成的 fixturepytest.fixture( params((10 * 1024, 100), (1024 * 1024, 10)), ids(small, large), ) def benchmark_file( request: pytest.FixtureRequest, tmp_path: pathlib.Path ) - BenchmarkFile: size, response_count request.param filepath tmp_path / sample.txt filepath.touch() os.truncate(filepath, size) return BenchmarkFile(filepath, response_count)关键设计点两个参数元组(10 * 1024, 100)表示 10 KB 文件、循环请求 100 次(1024 * 1024, 10)表示 1 MB 文件、循环请求 10 次。请求次数随文件变大而减少以控制整体基准运行时长同时保证大文件路径也有足够的采样。测试用例 idids(small, large)使 pytest 报告中清晰区分两档场景对应变更记录中的 small、large。文件生成方式在tmp_path下创建空文件后用os.truncate精确扩展到目标字节数避免依赖真实文件内容保证测试可复现。BenchmarkFile数据结构一个frozenTrue的 dataclass把文件路径与请求次数打包传给测试函数便于在参数化后保持代码整洁。这套参数化同时作用于两个基准测试函数使二者都能在两种文件大小下运行。三、两个被测函数sendfile 路径与 fallback 路径变更记录提到的两个函数分别覆盖web.FileResponse的两条发送路径1.test_simple_web_file_response—— 标准 sendfile 路径def test_simple_web_file_response( event_loop, aiohttp_client_sync, benchmark, conn_type, benchmark_file, pytestconfig, ) - None: async def handler(request: web.Request) - web.FileResponse: nonlocal server_transport server_transport request.transport return web.FileResponse(pathbenchmark_file.path) app web.Application() app.router.add_route(GET, /, handler) async def run_file_response_benchmark() - None: client await aiohttp_client_sync(app, server_kwargsconn_type.s_kwargs) for request_number in range(benchmark_file.response_count): response await client.get(/, **conn_type.c_kwargs) # Consume response. # Large responses may leave transport unclosed on at least python 3.10. await response.read() await client.close() benchmark def _run() - None: event_loop.run_until_complete(run_file_response_benchmark())该测试模拟“纯 sendfile”场景服务端路由返回web.FileResponse(path...)客户端用TestClient发起 GET 请求并调用response.read()完整消费响应体确保基准测量的是完整的数据传输过程而不是半途中断。测试中通过conn_typefixture 额外参数化了 tcp 与 sslTLS两种连接方式SSL 场景在 Python 3.12 上还会开启内核 TLSssl.OP_ENABLE_KTLS以贴近真实生产配置。2. fallback 路径测试变更记录中写作test_simple_web_file_response_fallback在源码中对应的实际函数名为test_simple_web_file_sendfile_fallback_response。它强制禁用 sendfileasync def handler(request: web.Request) - web.FileResponse: transport request.transport assert transport is not None transport._sendfile_compatible False # type: ignore[attr-defined] return web.FileResponse(pathbenchmark_file.path)通过把传输层的_sendfile_compatible置为False强制 aiohttp 走“不依赖 sendfile 系统调用”的兼容路径从而单独测量 fallback 分块发送的性能。3. 另一个相关基准304 Not Modified同文件中还有一个未参数化文件大小的基准test_simple_web_file_response_not_modified它先获取Last-Modified响应头再携带If-Modified-Since请求头发起 100 次请求断言响应状态为 304。它衡量的是命中 HTTP 缓存校验web.FileResponse的 ETag / Last-Modified 前置条件判断时零响应体的开销与上述两条“完整发送”路径形成互补。四、源码级原理为什么大小会影响 FileResponse 的发送行为要理解这次参数化改动的意义需要回到 aiohttp/web_fileresponse.py 的实现。FileResponse继承自StreamResponse的发送核心是_sendfile方法if NOSENDFILE or self.compression: return await self._sendfile_fallback(writer, fobj, offset, count) loop request._loop transport request.transport if transport is None: raise ConnectionResetError(Connection lost) try: if aiofastnet is not None: await aiofastnet.sendfile(loop, transport, fobj, offset, count) else: await loop.sendfile(transport, fobj, offset, count) except NotImplementedError: return await self._sendfile_fallback(writer, fobj, offset, count)从源码结构看存在两个决定性因素使发送路径产生分叉环境变量AIOHTTP_NOSENDFILE文件顶部NOSENDFILE bool(os.environ.get(AIOHTTP_NOSENDFILE))可全局禁用 sendfile响应压缩当FileResponse开启了压缩self.compression为真时无法直接零拷贝发送也必须退回 fallback平台支持当loop.sendfile抛出NotImplementedError例如某些自定义事件循环时同样自动降级。fallback 路径_sendfile_fallback的实现体现了“低内存占用”的设计目标通过loop.run_in_executor在线程池中执行fobj.read(chunk_size)按chunk_size默认来自helpers.DEFAULT_CHUNK_SIZE分块读取并writer.write直至count减到 0 或读完最后writer.drain()。大文件在此路径下会经历更多次分块读写这正是参数化 large 场景要覆盖的性能差异点。此外prepare()中大量逻辑与文件大小直接相关也值得注意Range 请求处理_prepare_open_file根据If-Range、http_range计算start/countstart file_size时返回 416并设置Content-Range: bytes */{file_size}合法区间返回 206 与Content-Range: bytes {start}-{startcount-1}/{file_size}。ETag 与 Last-ModifiedETag 由f{st.st_mtime_ns:x}-{st.st_size:x}生成天然包含文件大小信息配合If-Match/If-None-Match/If-Modified-Since/If-Unmodified-Since实现 304 与 412 语义。0 字节与空响应体count 0或请求方法/状态码要求空响应体时直接prepare跳过 sendfile因为对 0 字节调用 sendfile 会抛ValueError。这些逻辑的复杂度与文件大小、是否命中缓存相关参数化后基准数据能更真实地反映它们在两档规模下的表现。五、如何运行这些基准测试该基准套件基于pytest-codspeed插件benchmark fixture 来自pytest_codspeed.BenchmarkFixture它已在 aiohttp 的测试依赖中声明pytest_codspeed出现在 requirements/test-common.in、requirements/lint.in 中锁定版本为pytest-codspeed5.0.3见 requirements/test-common.txt。运行前先按仓库的pytest.ini约定安装测试依赖然后执行# 安装测试依赖含 pytest-codspeed pip install -r requirements/test.txt # 仅运行 web 文件响应基准 pytest tests/test_benchmarks_web_fileresponse.py运行时应注意 pytest.ini 中的若干全局配置对基准测试的影响--numprocessesautopytest-xdist默认启用基准测试属 CPU/IO 敏感场景若需精确测量建议单进程运行-n0或-p no:xdist--durations10会输出最慢的 10 个测试便于快速查看基准结果排序-m not dev_mode and not autobahn and not internal默认排除特殊标记套件不影响本基准timeout 120为每个测试设置 2 分钟超时pytest.ini注释说明 Autobahn 与基准测试任务在 CI 中会以--timeout0覆盖本地若遇超时可同样处理基准测试不依赖--cov但全局开启了 coverage 采集追求极致精度时可加--no-cov。运行后可从 pytest 的benchmark装饰器输出中分别读取 small / large以及 tcp / ssl组合下的耗时对比两条发送路径在不同文件规模下的性能曲线。六、变更的工程价值小结回顾 CHANGES/12913.misc.rst 记录的这次改动其价值可归纳为三点补全测量盲区把单一 11 KB 样本扩展为 10 KB 与 1 MB 两档使web.FileResponse的基准覆盖小文件头部、对象创建开销主导与大文件吞吐、分块、零拷贝效率主导两类截然不同的场景双路径对称覆盖标准 sendfile 路径与强制 fallback 路径在同一参数化体系下对齐便于横向对比零拷贝与非零拷贝实现的差距低侵入实现仅通过一个参数化 fixture 就完成了扩展测试主体逻辑零改动体现了 pytest 参数化的可组合性。对想深入源码的读者建议沿着 tests/test_benchmarks_web_fileresponse.py → aiohttp/web_fileresponse.py 的链路阅读前者展示基准如何组织后者解释_sendfile/_sendfile_fallback/_prepare_open_file的完整实现二者结合即可复现并验证本篇所述的两档参数化行为。赞分享后端Web框架WebSocket【免费下载链接】aiohttpAsynchronous HTTP client/server framework for asyncio and Python项目地址https://gitcode.com/gh_mirrors/ai/aiohttp点击查看免费下载相关推荐Xray性能基准测试不同文件大小下的编辑响应速度Xray性能基准测试不同文件大小下的编辑响应速度 测试环境与工具说明 Xray作为一款实验性的下一代基于Electron的文本编辑器其性能表现直接影响用户体开发工具TabbyJava代码安全漏洞检测的终极利器让代码审计效率提升10倍TabbyJava代码安全漏洞检测的终极利器让代码审计效率提升10倍 在当今数字化时代Java应用的安全问题日益凸显代码审计作为保障软件安全的关键环节应用安全静态分析漏洞扫描sherpa-onnx v1.10.45 发布解读FireRedAsr 语音识别全量接入sherpa onnx v1.10.45 发布解读FireRedAsr 语音识别全量接入 sherpa onnx v1.10.45 已发布。本次核心变化是完整人工智能语音音频本地部署上一篇Vue3Pinia状态管理在CcClip中的最佳实践下一篇7个高效NocoDB数据归档技巧轻松管理历史数据的完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Teleport Terraform Provider 资源开发指南:从新增资源到 legacy 迁移的完整实践

Teleport Terraform Provider 资源开发指南:从新增资源到 legacy 迁移的完整实践

网络安全认证鉴权运维后端 【免费下载链接】teleport The easiest, and most secure way to access and protect all of your infrastructure. 项目地址: https://gitcode.com/gh_mirrors/tel/teleport 点击查看 免费下载 本指南以 integrations/terraform/CONTRIB…

2026/9/21 2:19:13 阅读更多 →
Nix 源码调试指南:从带调试符号的构建到 gdb/lldb 断点实战

Nix 源码调试指南:从带调试符号的构建到 gdb/lldb 断点实战

开发工具CLI 【免费下载链接】nix Nix, the purely functional package manager 项目地址: https://gitcode.com/gh_mirrors/ni/nix 点击查看 免费下载 本篇指南面向需要深入 Nix(purely functional package manager)源码内部进行排障、内存…

2026/9/21 2:19:13 阅读更多 →
士兰微SC7A20H三轴加速度计在智能穿戴运动检测中的选型与实战

士兰微SC7A20H三轴加速度计在智能穿戴运动检测中的选型与实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/21 2:19:13 阅读更多 →

最新新闻

校招岗位信息操作系统:从搜索、解码到闭环的工程化方法

校招岗位信息操作系统:从搜索、解码到闭环的工程化方法

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/21 2:53:34 阅读更多 →
Fresco 渐进式 JPEG(Progressive JPEG)支持:网络流式解码原理与 Android 实战指南

Fresco 渐进式 JPEG(Progressive JPEG)支持:网络流式解码原理与 Android 实战指南

移动开发图像处理 【免费下载链接】fresco An Android library for managing images and the memory they use. 项目地址: https://gitcode.com/gh_mirrors/fr/fresco 点击查看 免费下载 渐进式 JPEG(Progressive JPEG)是提升弱网环境下图片…

2026/9/21 2:53:34 阅读更多 →
PX4直连遥控器控制舵机:绕过飞控逻辑的PWM硬实时方案

PX4直连遥控器控制舵机:绕过飞控逻辑的PWM硬实时方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/21 2:53:34 阅读更多 →
Browser Harness 跨源 iframe 操控指南:iframe_target 目标附着与合成器层坐标点击

Browser Harness 跨源 iframe 操控指南:iframe_target 目标附着与合成器层坐标点击

Browser Harness 跨源 iframe 操控指南:iframe_target 目标附着与合成器层坐标点击 【免费下载链接】browser-harness Browser Harness | Self-healing harness that enables LLMs to complete any task. 项目地址: https://gitcode.com/gh_mirrors/br/browser-ha…

2026/9/21 2:53:34 阅读更多 →
STM32 HardFault深度解析:寄存器快照与堆栈回溯实战指南

STM32 HardFault深度解析:寄存器快照与堆栈回溯实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/21 2:52:34 阅读更多 →
file_selector_ios:Flutter 官方 iOS 文件选择器插件的架构、UTI 过滤与实战指南

file_selector_ios:Flutter 官方 iOS 文件选择器插件的架构、UTI 过滤与实战指南

移动开发跨平台 【免费下载链接】plugins Plugins for Flutter maintained by the Flutter team 项目地址: https://gitcode.com/gh_mirrors/pl/plugins 点击查看 免费下载 导读 本文围绕 Flutter 团队维护的联邦插件体系中的 iOS 端实现 file_selector_ios 展开&…

2026/9/21 2:52:34 阅读更多 →

日新闻

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程 【免费下载链接】agentic-awesome-skills AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and …

2026/9/21 0:00:01 阅读更多 →
gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析 【免费下载链接】gin-vue-admin 🚀ViteVue3Gin拥有AI辅助的基础开发平台,企业级业务AI开发解决方案,内置mcp辅助服务,内置skills管理,…

2026/9/21 0:00:01 阅读更多 →
Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

桌面应用AI 应用插件系统 【免费下载链接】Wox A cross-platform launcher that simply works 项目地址: https://gitcode.com/gh_mirrors/wo/Wox 点击查看 免费下载 全功能插件(Full-featured Plugin)是 Wox 三类插件实现方式中能力最完整的…

2026/9/21 0:00:01 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/20 0:00:46 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/21 2:19:36 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/20 0:00:46 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/19 23:01:36 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/19 17:50:38 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →