许多开发人员在接到性能分析任务时,脑子里都不清楚他们要通过分析得到什么。所有开发人员或经理在开始做这件事时经常只是模模糊糊地感觉代码“应该跑得更快”。
但这是彻底的倒退。要进行真正有效的性能调优,在开始做任何技术类工作之前,你应该先认真考虑下面这些问题并找出答案。
- 你正在测量的代码有哪些可观测的环节?
- 如何测量那些可观测环节?
- 这些可观测环节的目标是什么?
- 你怎么判断性能调优是否做好了?
- 性能调优可接受的最大支出是多少(按开发人员投入的时间和增加的代码复杂度计算)?
- 在优化的过程中,哪些东西是你不能舍弃的?
最重要的,也是我们要反复强调的,就是你必须测量。你至少得测量一个可观测环节,才算得上是在做性能分析。
当你开始测量代码,便经常会发现事情并非你想的那样。很多性能问题的根源可能是一个丢失的数据库索引,或者有争议的文件系统锁。在优化代码时,你应该时刻牢记代码很可能不是问题的关键。为了定量分析问题,你首先需要知道自己在测量什么。
6.2.1 知道你在测量什么
做性能调优必须测量一些东西。如果你没有测量可观测环节,就不能算做性能调优。坐在那里盯着代码,希望脑子里蹦出一个可以更快解决问题的方法,这可不是性能分析。
提示 要成为优秀的性能工程师,你必须知道平均数、中位数、模式、方差、百分位数、标准差、样本大小、正态分布等这样一些术语。如果还不熟悉这些概念,最好现在就到网上搜搜,如果有必要的话,认真看看搜出来的内容。
做性能分析最重要的是知道哪个可观测环节(上节介绍的)最重要。你应该总是把测量结果、目标和结论跟一个或多个基本可观测环节结合起来。
这里有些常见的可观测项,都是性能调优的好对象。
- 方法
handleRequest
运行所需的平均时间(启动完成之后)。 - 并发客户端数量为10时,系统等待时间的第90个百分位数。
- 把并发用户数从1增长到1000时,响应时间的退化。
以上这些都是工程师想要测量的代表性数值,并很有可能需要优化。想得到准确又有用的数值,必须掌握基本的统计学知识。
知道你要测量什么,对数值的准确性有信心是性能调优的第一步。但模糊或随意的目标通常没什么好结果,性能调优也是如此。
6.2.2 知道怎么测量
要精确确定一个方法或其他代码片段运行需要多长时间,只有两种方法:
- 直接测量,在类源码中插入测量代码;
- 在类加载时把类转换成受测类。
大多数简单直接的性能测量技术都依赖于以上其中一种或全部技术。
还应该提一下JVM工具接口(JVMTI),用它可以创建非常复杂的分析器,但它也有缺陷。它需要性能工程师编写本地代码,并且它产生的分析数值本质上是统计平均值,而不是直接测量结果。