用途:该工作流用于测量并优化受约束 Noir 程序的 ACIR 电路规模,目标是降低门数与 ACIR 操作数。不适用于非约束(Brillig)函数,Brillig 运行在常规虚拟机上,应使用常规性能分析,bb gates 无法反映其性能。
测量方式:二进制项目执行 nargo compile && bb gates -b ./target/<package>.json。库项目无法用 nargo compile,需给待测函数加 #[export] 后执行 nargo export && bb gates -b ./export/<function_name>.json,产物写入 export/ 目录并以导出函数名命名。若没有 bb,需向用户询问其后端对应的等价命令。
输出含两个字段:circuit_size 为后端编译后的实际门数,决定证明时间,通常是瓶颈;acir_opcodes 为 ACIR 操作数,影响执行时间(见证生成)。两者可能此消彼长,冲突时优先 circuit_size。改动前须记录两者的基线。
优化循环:先编译并记录 circuit_size 基线;每次只应用一项改动;重新编译并对比基线;若 circuit_size 上升或不变则回退;再尝试下一项候选改动。
可尝试的优化(大致按影响排序):用非约束 hint 加约束验证替换昂贵的电路内计算,这是多数程序影响最大的优化;减少 hint 内容,若在 hint 中间值(选择器、掩码、索引),尝试只 hint 最终结果并直接验证;把断言提出分支,将 if c { assert_eq(x, a) } else { assert_eq(x, b) } 改为 assert_eq(x, if c { a } else { b });简化比较,不等检查(<、<=)比相等(==)开销更大,但不要为规避而引入额外状态,先测量。
不应尝试:不要 hint 除法或模运算,编译器已注入非约束辅助;不要手写条件选择,if/else 表达式与 c * (a - b) + b 编译结果相同;不要在未测量的情况下用标志跟踪替换 <=,跨循环迭代增加可变状态可能产生更多门。