性能管理 — 您有规划吗?
原文:http://www-128.ibm.com/developerworks/cn/java/j-jtp03253/
知道何时优化比知道如何优化更重要
Brian Goetz
首席顾问, Quiotix Corp
2003 年 6 月 21 日
性能问题从何而来?导致性能问题的编程选项有许多类型 — 效率低的算法、冗余计算、糟糕的资源分配和使用情况、过多的同步,或者很明显就是效率低的设计。但更普遍的且具有破坏性的要属管理和方法错误,而不是编程错误。在这一部分的 Java 理论与实践中,Brian Goetz 将讨论在项目中使用 Java 语言时遇到的一些最常见的性能错误。在附带的 论坛中与作者和其他读者分享您关于本文的心得。(您也可以通过单击本文顶部或底部的 讨论来访问该论坛。)
性能管理通常被视为一种巫术,因为性能问题通常在应用程序开发完成之后才会出现。到那时,就难以确定它们的根源。然而,一旦十分准确地确定了性能问题的起因,那么修正它常常是比较简单的事情。工程师在寻找更有效的方法来执行特殊任务方面通常具有相当的创造性(有时他们的创造性过了头)。对于任何给定的性能问题,通过使用高速缓存来减少冗余计算或者只是添加更多的硬件,解决方案可能会与用更有效的算法进行替换一样简单。但是,要清楚地确定性能问题的根源会很困难,而设计复杂程序甚至 更加困难,所以首先要使它们没有性能问题。
虽然编程决策 — 如算法或数据表示的次优(sub-optimal)选择,无法重用先前计算的结果,或者糟糕的资源管理 — 通常被认为是性能问题的直接起因,但大多数性能问题还有一个更深的起因:无法首先将性能管理、目标和测量集成到开发过程中。
问题?什么问题?
您如何知道何时有性能问题呢?对于大多数开发团队,回答(用美国高级易做图法官 Potter Stewart 对罪行描述的话来讲)是:在遇到时才知道。这是问题的核心 — 性能目标、度量和测量常常没被考虑到,直到发现时,已经太晚了。
最常见的性能管理策略是……也没什么,它通常采用下列两种形式之一:
在应用程序开发完成之前完全忽略性能
开发时进行优化,这通常意味着只关注极微小的性能考虑事项,而忽略较大的方面
这两种策略共有同一个基本问题 — 它们没有将性能管理视作开发过程的一个集成部分。
有缺陷的性能策略 A:完全忽略性能
第一种方法是完全忽略性能,该方法将性能视作可以在项目结束时处理的事情,比如象编写发行说明或构建安装程序。该策略基本上靠运气,因为计算机运算速度一年比一年快,所以在性能方面总能够应付得过去。
这种靠运气的问题(即使当成功的可能性非常大时)就是:当出现性能问题时,您没有处理它、确定其根源或以特别方式解决它的框架。您也没有在开发规划中安排用于性能测量和调优的时间。这有点象网站,除了安装具有缺省配置的防火墙外,没有尝试使用一个连贯的安全性策略,然后发现它们已经被窃取。您从何处着手呢?
有缺陷的性能策略 B:开发时进行优化
另一个常见但甚至更糟的方法是让极微小的性能考虑事项驱动体系结构和设计决策。开发人员喜欢优化代码,其正当理由就是它令人满意和带来乐趣。但是,就关注的代码以及在开发周期中解决性能问题的时机而言,知道何时优化更为重要。遗憾的是,开发人员一般无法凭直觉判断性能问题将实际出现在应用程序的哪个位置。结果,他们浪费了大量精力对很少执行的代码路径进行优化,或者更糟的是,他们损害好的设计和开发实践来优化早先没有任何性能问题的组件。当您埋头编写代码时,很容易在性能问题上只见树而不见林。
使各个代码路径尽可能快地运行并不保证最终产品会很好地执行。再怎么进行局部优化都不可能弥补根本上效率低的设计,即使将每个组件实现为尽可能的快,也是如此。开发时优化策略用关注低级别的性能考虑事项来替代对整个项目实施的性能策略,而且让您无法确信您真正有一个性能策略。
开发时进行优化的许多问题之一是它忽略了优化中的固有风险。少数优化也会使设计更佳,错误更少,但这些都是例外情况。通常,优化涉及性能和其它考虑事项(如干净的设计、明确性、灵活性和功能性)之间的权衡。优化会付出一定的成本和风险:它可能会引入错误、限制代码的功能性或者使使用或维护变得更加困难。在承受这些成本之前,请确保值得这样做。
将性能管理作为开发过程的一部分
从一开始就应该将性能测量和规划集成到开发过程中,对开发和性能测量和调优进行单独、交错的迭代。这意味着设定性能目标、准备性能测量方案以及在开发代码时经常复查代码性能。最好将旧的测试结果保存在数据库中,这样您可以容易地比较当您更改代码时性能的变化情况。
对开发和性能进行单独的迭代,可让您在开发迭代期间集中精力编写起作用的无错误的代码,如果需要的话,您还会知道不久将有一个适当的机会来改进性能。如果您想起一个使代码运行更快的巧妙窍门,那么在代码中加一个注释以详细描述您的想法,但现在不要实现!现在不是进行优化的时候。 如果最终必需这么做,则当您关注性能时再返回来。性能优化应该由性能目标驱动,并受性能测量支持。别的东西不过是“次要的”。
测量两次,然后再测量几次
测量是性能管理的关键元素。想一下:一个给定的妙计将使代码运行得更快吗?我们准备验证这一点。在实施妙计的 前后,使用性能测量工具来测试性能。如果您没有测到有改进,该怎么办?那么,准备收回您的妙计。如果您测不出有好处,那为什么要冒破坏工作代码的风险呢?
在性能迭代期间,测量应用程序或其组件的性能,并将它们与先前迭代的测量比较。有些方面慢下来了吗?找出原因。如果它达不到性能目标,那么您不一定非得更改它,但现在您已经获得了有价值的、有关您更改后对性能影响的反馈信息。
达到目标了吗?
如果您没有定量的性能目标和支持它们的测量规划,那么性能调优似乎是无意义的。您如何知道您已经达到目标了?其它开发阶段(如编码、测试和打包)都定义了目标 — 实现这组功能、修正这些错误等等。性能阶段也应该有结构和目标。
当对性能的关注是源自于外部时(不管是客户还是公司内的另一个部门),具有性能目标尤为重要。当某人告诉您使程序运行得更快时,您应该先问一下“我必须使它快多少?”否则,您可能会在调优方面投入过多的资源,但仍不能使客户满意。投入十二分的精力来使程序运行速度提高 30%,不料却有人反应“哎呀,我原希望速度能提高 50%。”,这会让人很失望。
结束语
性能管理不仅包括优化,还包含许多其它东西。它有一个用于决定何时优化何时不优化的框架。您应该根据明确的性能目标、测量和规划来做这些决策,而不是直觉。
参考资料
您可以参阅本文在 developerWorks 全球站点上的 英文原文.
参与有关本文的 论坛。(您也可以通过单击本文顶部或底部的 讨论来访问该论坛。)
Jack Shirazi 撰写的 Java Performance Tuning (OReilly & Associates,2003)一书包含了大量有关个别优化以及如何测量性能和智能地处理性能调优的建议。
Jack Shirazi 的 Java Performance Tuning网站包含了许多与性能相关的文章和技巧的链接。
由 Steve Wilson 与 Jeff Kesselman 合著的 Java Platform Performance: Strategies and Tactics (Addison-Wesley,2000)包含了一些对在 Java 类库开发期间遇到的实际性能问题的深入案例研究。
另一个由 Brian Goetz 撰写的第三方“ Design for Performance”系列文章( JavaWorld)提供了有关设计决策如何影响性能的一些技巧。
文章“ Spotlight on Java performance”( developerWorks,2001 年 12 月)说明了一个用于 IBM Java 虚拟机项目的明智且实用的性能管理策略。
“ Optimize your Java applications performance”( developerWorks,2002 年 6 月)演示了一个迭代式性能调优策略,它使用算法改进、高速缓存和低级别性能调优。
在 developerWorksJava 技术专区 可找到数百篇有关 Java 技术的参考资料。
关于作者
Brian Goetz 是一位软件顾问,在过去的 15 年里一直是一位专业软件开发人员。他是 Quiotix的首席顾问,该公司是位于加利福尼亚 Los Altos 的软件开发和咨询公司。请在业界流行的出版物上查阅 Brian 已发表的和即将发表的文章。可以通过 brian@quiotix.com与 Brian 联系。
补充:软件开发 , Java ,