如何用 gen_snapshot 的 --print-instructions-sizes-to 对比改动前后的 AOT snapshot 体积
2026/9/10 11:36:17 网站建设 项目流程

如何用 gen_snapshot 的 --print-instructions-sizes-to 对比改动前后的 AOT snapshot 体积

【免费下载链接】flutterFlutter makes it easy and fast to build beautiful apps for mobile and beyond项目地址: https://gitcode.com/GitHub_Trending/flutter41/flutter

如果你改动了 Dart 代码或重建了 Flutter Engine,想知道这次改动让 AOT snapshot 变大还是变小、具体哪些方法贡献了增量,可以按 Flutter 仓库中 AOT snapshot 体积对比指南 的流程来做:先用flutter build aot --verbose找到gen_snapshot的原始调用,加上--print-instructions-sizes-to参数各跑一次,把两次输出分别存成before.jsonafter.json,最后用文档给出的compare_size.dart工具生成逐方法的体积差异表。

前提是在主机上已经按 Setting-up the Engine development environment 搭好 Flutter Engine,并且在文中所有命令里用FLUTTER_ENGINE这个环境变量指向 engine 的本地目录(指南开头即以该路径引用 engine 位置)。

先构建一次并记录 gen_snapshot 的原始调用

构建应用的 AOT snapshot 时给flutter build aot加上--verbose标志,目的是从输出里找到gen_snapshot被调用的完整命令行——稍后需要复跑这条命令并追加一个参数。

如果本次构建用的是本地构建的 engine,构建命令还要同时带上--local-engine--local-engine-host两个 flag,参见 Debugging the engine。

给 gen_snapshot 追加 --print-instructions-sizes-to,生成 before.json

从 verbose 输出里拿到gen_snapshot调用后,原样复跑,并追加--print-instructions-sizes-to参数,指向一个 JSON 文件路径(指南中称为SUMMARY_LOCATION)。文档给出的示例调用如下:

$FLUTTER_ENGINE/out/host_debug_unopt/gen_snapshot \ --print-instructions-sizes-to=$SUMMARY_LOCATION \ --causal_async_stacks \ --packages=.packages \ --deterministic \ --snapshot_kind=app-aot-blobs \ --vm_snapshot_data=build/aot/vm_snapshot_data \ --isolate_snapshot_data=build/aot/isolate_snapshot_data \ --vm_snapshot_instructions=build/aot/vm_snapshot_instr \ --isolate_snapshot_instructions=build/aot/isolate_snapshot_instr \ build/aot/app.dill

其中$SUMMARY_LOCATION需要替换为你自己想保存的 JSON 文件路径;gen_snapshot二进制的路径示例中用的是host_debug_unopt配置目录,其余参数(--packagesbuild/aot下的四个快照输出、app.dill输入等)以你 verbose 输出中实际找到的调用为准。

跑完后,把SUMMARY_LOCATION指向的这个文件保存为before.json,作为改动前的基线。

做改动后重新走一遍:重建 AOT 快照再复跑 gen_snapshot

改动可以有两类:修改 Dart 代码(观察代码改动的影响),或者重新构建 engine 得到新的gen_snapshot二进制(观察 engine 本身改动的影响)。

改动完成后,先重新执行一次flutter build aot。这一步不能跳过,因为 AOT 编译在调用gen_snapshot之前还有一次 kernel 编译步骤,直接复跑旧调用的话,输入给gen_snapshotapp.dill不会反映你的改动(kernel 编译步骤的说明见 Custom Flutter Engine Embedding in AOT Mode)。

然后按上一步的方式重新执行gen_snapshot(同样带--print-instructions-sizes-to),把这次产生的 JSON 文件保存为after.json

用 compare_size.dart 生成对比摘要

接下来运行compare_size.dart工具,把before.jsonafter.json作为参数传入,生成汇总表。文档给出的调用示例形式如下:

$FLUTTER_ENGINE/out/host_debug_unopt/dart-sdk/bin/dart \ before.json \ after.json

执行后控制台会输出一个按 Library / Method / Diff (Bytes) 分列的差异表,正数表示该方法编译出的指令变大了,负数表示变小,最后一行给出总变化量。下面是文档中的示例输出(示例结果,具体数值因你的改动而异):

+------------+----------------------------------------------------------+--------------+ | Library | Method | Diff (Bytes) | +------------+----------------------------------------------------------+--------------+ | dart:async | new ZoneSpecification.from | +2136 | | dart:async | runZoned | +1488 | | dart:async | new _CustomZone | +927 | ... | | [Stub] Type Test Type: class 'PopupMenuEntry' | -128 | | dart:io | new Directory | -211 | +------------+----------------------------------------------------------+--------------+ Total change +24036 bytes.

拿到这个表就完成了本次对比:从逐方法的 Diff 列可以看到体积变化集中在哪些库和方法上,Total change一行给出整体增减。

流程限制与注意事项

  • 对比的前提是before.jsonafter.json来自同一应用、同一gen_snapshot二进制下的两次构建;如果要对比的是 engine 改动,则两次分别使用改动前后的gen_snapshot,此时差异反映的是 engine 编译产物的变化而不是 Dart 代码的变化。
  • flutter build aot必须在两次 gen_snapshot 复跑之间各执行一次,否则 kernel 快照不更新,对比结果没有意义。
  • 整个流程依赖本地 engine 环境(FLUTTER_ENGINEout/host_debug_unopt下的gen_snapshotdart-sdk/bin/dart),仅靠发行版 Flutter SDK 无法按此路径操作。

完整流程、参数与示例见 Comparing AOT Snapshot Sizes。

【免费下载链接】flutterFlutter makes it easy and fast to build beautiful apps for mobile and beyond项目地址: https://gitcode.com/GitHub_Trending/flutter41/flutter

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询