Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

性能分析

复习

  • 日志与调试:先观察,再动手
  • 大 O 记号:描述代价随规模的增长
  • 循环优化:优化优先盯热点

TL;DR

  • 优化之前先测量,别凭感觉
  • 性能分析用来找出真正的瓶颈
  • 瓶颈往往集中在少数热点上
  • 先测再改,改后再测

正文

  程序能跑,但可能有点慢。想让它更快,第一反应往往是“我觉得这里慢,改改看”。这恰恰是最容易走弯路的地方。

别凭感觉优化

  有一条很有名的忠告:过早优化是万恶之源。 它想说的不是“不要优化”,而是不要凭直觉优化

  因为人对性能瓶颈的直觉,常常是错的。你以为最耗时的那个函数,实际可能根本没被调用几次;真正拖慢程序的,也许藏在一个你从没注意的角落。在没有数据的情况下优化,很可能是在做无用功,甚至把代码改得更复杂、更慢。

先测量,找瓶颈

  正确的做法是先测量性能分析(profiling)就是干这个的:它统计出程序把时间都花在了哪里——哪个函数调用最多、哪段代码最耗时。

  有了分析结果,你会发现一个很普遍的现象:瓶颈往往高度集中——可能 80% 的时间,都花在 20% 的代码上。这就是所谓的“热点”。

  这和前面讲算法、讲循环优化时的思路完全一致:把力气花在真正的热头上。 区别只在于,这里的“热点”是靠实测找出来的,而不是靠猜。

测—改—再测

  找到热点之后,优化它,然后再测量一次

  • 确实变快了吗?
  • 会不会把瓶颈转移到了别处?
  • 有没有引入新的问题?

  因为优化常常是“按下葫芦浮起瓢”:这里快了,别处成了新瓶颈。所以要循环往复:测量 → 优化 → 再测量,直到达到目标。

  用数据说话,而不是用感觉。 这条原则,从调试一直贯穿到性能优化。

思考题 1

  为什么优化前要先“测量”?

思考题 2

  为什么性能瓶颈常常集中在少数热点上?

小结

知识点

  • 不要凭直觉优化,应先测量
  • 性能分析找出时间花在哪里
  • 瓶颈常集中在少数热点代码
  • 采用“测量—优化—再测量”的循环

参考资料

  1. Wikipedia(zh):性能分析:测量程序各部分的资源消耗
  2. Wikipedia(zh):性能工程:以测量为基础改进系统性能

思考题答案(仅供参考)

思考题 1

  因为人对瓶颈的直觉常常不准,可能优化了根本不影响性能的地方,白费力气甚至弄糟代码。先测量才能知道时间真正花在哪里,让优化有的放矢。

思考题 2

  因为程序各部分被执行的频率和耗时差异很大:少数代码会被大量重复执行(热点),占据了大部分时间,而多数代码很少运行。因此把优化集中在这些热头上,收益最高。

协议

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

封面图

设计师 | 南国微雪