Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

无用代码删除

复习

  • 常量传播:把确定是常量的变量替换为常量
  • 数据流分析:活跃变量分析
  • 控制流图:判断可达性

TL;DR

  • 无用代码指永远不会执行、或结果没人使用的代码
  • 分为不可达代码与死代码两类
  • 它们依赖可达性分析和活跃变量分析来发现
  • 删除它们能减小体积、提升速度

正文

  常量传播常常会“算死”一些分支,从而暴露出那些永远不会执行的代码。把这些没用的代码删掉,就是无用代码删除(dead code elimination)。

两类“没用”

  “没用”分两种:

  • 不可达代码:根本执行不到。比如某个条件在编译期就能判定恒假,它包住的那段代码永远不会运行
  • 死代码:会执行,但结果没有人用。比如算出一个值,却从来没有被读取过

  前者是“走不到”,后者是“白算了”。

靠分析来发现

  怎么知道哪些代码没用?还是靠前面的分析:

  • 可达性分析:从入口出发,哪些块根本到不了,就是不可达代码
  • 活跃变量分析:某个变量算出来之后,后面还有没有人用;没人用,那段计算就是死代码

  举个小例子:

x = 1
x = 2
用 x

  第一次给 x 赋的 1,立刻被 2 覆盖了,从没被读过——这就是死代码,可以删掉。

小心副作用

  但删“结果没人用”的代码时,必须格外小心一件事:它有没有副作用?

  如果那行代码虽然结果没人用,却会打印、写文件、修改共享状态,那它就不能被当成“没用”删掉——因为它对外的影响是有人“用”的。只有真正“纯”的计算,才允许因为结果没人用而被删除。

  这也再次呼应了优化的第一原则:删可以,但行为不能变。

思考题 1

  “不可达代码”和“死代码”,有什么区别?

思考题 2

  删除“结果没人用”的代码时,为什么还要小心?

小结

知识点

  • 无用代码分为不可达代码与死代码
  • 可达性分析发现不可达代码
  • 活跃变量分析发现死代码
  • 有副作用的代码不能因“结果没人用”而删除

参考资料

  1. Wikipedia(zh):死代码消除:移除不会影响结果的代码
  2. Wikipedia(zh):活跃变量分析:判断变量之后是否还会被使用

思考题答案(仅供参考)

思考题 1

  不可达代码是根本执行不到的代码(例如恒假条件包住的代码);死代码是会执行、但产生的结果没有任何人使用。前者“走不到”,后者“白算了”。

思考题 2

  因为有些代码虽然结果没人用,却带有副作用(打印、写文件、改共享状态等)。这些副作用是外部的可观察行为,删除它会改变程序行为,违反优化原则。所以只有纯计算才允许删。

协议

  本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

封面图

设计师 | 南国微雪