性能优化指南:性能优化的一般性原则与方法

  

【本文转自博客园xybaby原文链接:https://www.cnblogs.com/xybaby/p/9055734.html】
  作为一个程序员,性能优化是常有的事情,不管是桌面应用还是web应用,不管是前端还是后端,不管是单点应用还是分布式系统。本文从以下几个方面来思考这个问题:性能优化的一般性原则,性能优化的层次,性能优化的通用方法。本文不限于任何语言,框架,不过可能会用Python语言来举例。   

  

  不过囿于个人经验,可能更多的是从Linux服务端的角度来思考这些问题。   

  

  <强>一般性原则   

  

  <强>依据数据而不是凭空猜测   

  

  这是性能优化的第一原则,当我们怀疑性能有问题的时候,应该通过测试,日志,profillig来分析出哪里有问题,有的放矢,而不是凭感觉,撞运气。一个系统有了性能问题,瓶颈有可能是CPU、有可能是内存,有可能是IO(磁盘IO,网络IO),大方向的定位可以使用前以及统计系列来定位(vmstat, iostat, netstat…),针对单个进程,可以使用pidstat来分析。   

  

  在本文中,主要讨论的是CPU相关的性能问题。按照80/20定律,绝大多数的时间都耗费在少量的代码片段里面,找出这些代码唯一可靠的办法就是侧面,我所知的编程语言,都有相关的概要文件工具,熟练使用这些资料工具是性能优化的第一步。   

  

  <强>忌过早优化   

  

  真正的问题是,程序员花了太多时间担心效率在错误的地方,在错误的时间;过早的优化是万恶之源(或者至少是大部分)编程。   

  

  我并不十分清楚Donald Knuth说出这句名言的上下文环境,但我自己是十分认同这个观念的。在我的工作环境(以及典型的互联网应用开发)与编程模式下,追求的是快速的迭代与试错,过早的优化往往是无用功,而且,过早的优化很容易拍脑袋,优化的点往往不是真正的性能瓶颈。   

  

  <强>忌过度优化   

  

  作为程序的性能规范的一部分——一个程序不可用缓慢的不适合的目的   

  

  性能优化的目标是追求合适的性价比。   

  

  在不同的阶段,我们对系统的性能会有一定的要求,比如吞吐量要达到多少多少。如果达不到这个指标,就需要去优化。如果能满足预期,那么就无需花费时间精力去优化,比如只有几十个人使用的内部系统,就不用按照十万在线的目标去优化。   

  

  而且,后面也会提到,一些优化方法是“有损”的,可能会对代码的可读性、可维护性有副作用。这个时候,就更不能过度优化。   

  

  <强>深入理解业务   

  

  代码是服务于业务的,也许是服务于最终用户,也许是服务于其他程序员。不了解业务,很难理解系统的流程,很难找出系统设计的不足之处。后面还会提及对业务理解的重要性。   

  

  <>强性能优化是持久战   

  

  当核心业务方向明确之后,就应该开始关注性能问题,当项目上线之后,更应该持续的进行性能检测与优化。   

  

  现在的互联网产品,不再是一锤子买卖,在上线之后还需要持续的开发,用户的涌入也会带来性能问题。因此需要自动化的检测性能问题,保持稳定的测试环境,持续的发现并解决性能问题,而不是被动地等到用户的投诉。   

  

  <强>选择合适的衡量指标,测试用例,测试环境   

  

  正因为性能优化是一个长期的行为,所以需要固定衡量指标,测试用例,测试环境,这样才能客观反映性能的实际情况,也能展现出优化的效果。   

  

  衡量性能有很多指标,比如系统响应时间,系统吞吐量,系统并发量。不同的系统核心指标是不一样的,首先要明确本系统的核心性能诉求,固定测试用例;其次也要兼顾其他指标,不能顾此失彼。   

  

  测试环境也很重要,有一次突然发现我们的每秒高了许多,但是程序压根儿没优化,查了半天,才发现是换了一个更牛逼的物理机做测试服务器。   

  

<>强性能优化的层次   

  

  按照我的理解可以分为需求阶段,设计阶段,实现阶段,越上层的阶段优化效果越明显,同时也更需要对业务,需求的深入理解。   

  

  <强>需求阶段   

  

  不战而屈人之兵,善之善者也   

性能优化指南:性能优化的一般性原则与方法