noir-optimize-acir
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseACIR Optimization Loop
ACIR优化循环
This workflow targets ACIR circuit size for constrained Noir programs. It does not apply to (Brillig) functions — Brillig runs on a conventional VM where standard profiling and algorithmic improvements apply instead, and won't reflect Brillig performance.
unconstrainedbb gates本工作流针对受约束Noir程序的ACIR电路大小进行优化。它不适用于(Brillig)函数——Brillig在传统虚拟机上运行,适用标准性能分析和算法改进,且无法反映Brillig的性能。
unconstrainedbb gatesMeasuring Circuit Size
测量电路大小
Binary projects
二进制项目
Compile the program and measure gate count with:
bash
nargo compile && bb gates -b ./target/<package>.json编译程序并使用以下命令测量门数:
bash
nargo compile && bb gates -b ./target/<package>.jsonLibrary projects
库项目
Libraries cannot be compiled with . Instead, mark the functions you want to measure with and use :
nargo compile#[export]nargo exportbash
nargo export && bb gates -b ./export/<function_name>.jsonArtifacts are written to the directory and named after the exported function (not the package).
export/If is not available, ask the user for their backend's equivalent command. Other backends should have a similar CLI interface.
bbThe output contains two fields:
- : the actual gate count after backend compilation. This determines proving time, which is generally the bottleneck.
circuit_size - : number of ACIR operations. This affects execution time (witness generation). A change can reduce opcodes without affecting circuit size or vice versa — both matter, but prioritize
acir_opcodeswhen they conflict.circuit_size
Always record a baseline of both metrics before making changes.
库无法使用编译。相反,为你要测量的函数添加标记,然后使用:
nargo compile#[export]nargo exportbash
nargo export && bb gates -b ./export/<function_name>.json产物会被写入目录,文件名以导出的函数命名(而非包名)。
export/如果没有工具,请询问用户其后端对应的等效命令。其他后端应具备类似的CLI界面。
bb输出包含两个字段:
- :后端编译后的实际门数。这决定了证明时间,通常是性能瓶颈。
circuit_size - :ACIR操作的数量。这会影响执行时间(见证生成)。优化可能减少操作码但不影响电路大小,反之亦然——两者都很重要,但当两者冲突时,优先考虑
acir_opcodes。circuit_size
在进行修改前,务必记录这两个指标的基准值。
Optimization Loop
优化循环
- Baseline: compile and record .
circuit_size - Apply one change at a time.
- Recompile and measure: compare to the baseline.
circuit_size - Revert if worse: if increased or stayed the same, undo the change. Not every "optimization" helps — the compiler may already handle it, or the overhead of the new approach may outweigh the savings.
circuit_size - Repeat from step 2 with the next candidate change.
- 基准测试:编译并记录。
circuit_size - 每次仅应用一项修改。
- 重新编译并测量:将与基准值比较。
circuit_size - 如果效果变差则回滚:如果增加或保持不变,撤销修改。并非所有"优化"都有效——编译器可能已经处理了相关问题,或者新方法的开销超过了节省的成本。
circuit_size - 重复:回到步骤2,进行下一项候选修改。
What to Try
可尝试的优化方法
Candidate optimizations roughly ordered by impact:
- Hint and verify: replace expensive in-circuit computation with an unconstrained hint and constrained verification. This is the highest-impact optimization for most programs.
- Reduce what you hint: if you're hinting intermediate values (selectors, masks, indices), see if you can hint only the final result and verify it directly.
- Hoist assertions out of branches: replace with
if c { assert_eq(x, a) } else { assert_eq(x, b) }.assert_eq(x, if c { a } else { b }) - Simplify comparisons: inequality checks (,
<) cost more than equality (<=). But don't introduce extra state to avoid them — measure first.==
候选优化方法按影响大致排序:
- 提示与验证:将电路内的昂贵计算替换为无约束的提示和有约束的验证。这对大多数程序来说是影响最大的优化手段。
- 减少提示内容:如果你正在提示中间值(选择器、掩码、索引),看看是否可以仅提示最终结果并直接验证。
- 将断言提升到分支外:替换为
if c { assert_eq(x, a) } else { assert_eq(x, b) }。assert_eq(x, if c { a } else { b }) - 简化比较操作:不等式检查(、
<)的成本高于相等性检查(<=)。但不要为了避免它们而引入额外状态——先进行测量。==
What Not to Try
不建议尝试的操作
- Don't hint division or modular arithmetic: the compiler already injects unconstrained helpers for these.
- Don't hand-roll conditional selects: expressions compile to the same circuit as
if/else.c * (a - b) + b - Don't replace with flag tracking without measuring: adding mutable state across loop iterations can produce more gates than a simple comparison.
<=
- 不要对除法或模运算使用提示:编译器已经为这些操作注入了无约束的辅助函数。
- 不要手动实现条件选择:表达式编译后的电路与
if/else相同。c * (a - b) + b - 不要在未测量的情况下用标志跟踪替换:在循环迭代中添加可变状态可能会比简单的比较产生更多的门。
<=