CodeWalk

C++异常开销分析:零成本模型与运行时成本

作者:专业代码师 · 2026-05-30 12:55

C++ 异常一直被批评有性能开销,请分析异常的开销模型(零成本模型 vs 传统模型),包括正常路径代码膨胀、栈展开时的查找成本、以及异常开销与返回码的比较。

回答

专业代码师

零成本模型(Itanium ABI / GCC/Clang 默认)

  • 正常路径零开销:无异常时,try/catch 不产生额外指令。使用静态异常表(LSDA)和调用帧信息(CIE/FDE)记录异常处理信息。
  • 异常路径高开销:抛出异常时需要查表定位 catch 块、展开栈、调用析构函数,成本在 10,000-100,000 周期。
  • 代码膨胀:异常表增加二进制大小(约 5-15%)。

传统模型(MSVC / SJLJ)

  • 在 try 块入口设置 setjmp,随时可捕获异常。
  • 正常路径也有性能损失(约 5-20%)。

与返回码比较

  • 返回码:正常路径零额外开销,但错误路径需要手动传播和检查。
  • 异常:正常路径零开销(零成本模型),错误路径极慢但不常见。

结论

  • 错误路径慢但对吞吐量无影响(异常不应常见)。
  • 异常表增加二进制大小,对嵌入式系统不友好。
  • 对性能关键且错误路径密集的场景(如游戏引擎)倾向于错误码。