关于性能的更多思考
什么是性能?
#性能是执行者一系列可量化属性的集合。
在此上下文中,性能不是执行行为本身;而是某事物或某人执行得有多好。因此,我们使用形容词 performant。
虽然 执行得有多好 的部分通常可以用自然语言来描述,但在我们有限的范围内,重点关注的是可以量化为实数的内容。实数包括整数以及作为特殊情况的 0/1 二进制数。自然语言描述仍然非常重要。例如,一篇仅用词语而非数字(可量化值)来严重批评 Flutter 性能的新闻文章仍然可能有意义,并可能产生巨大影响。选择有限的范围仅仅是因为我们资源有限。
描述性能所需的量通常被称为指标。
要浏览无数的性能问题和指标,可以根据执行者进行分类。
例如,本网站上的大部分内容都与 Flutter 应用性能相关,其中执行者是 Flutter 应用。基础架构性能对 Flutter 也很重要,其中执行者是构建机器人和 CI 任务运行器:它们极大地影响 Flutter 集成代码更改的速度,从而提高应用的性能。
在此,范围被故意扩大,以包含应用性能问题以外的性能问题,因为它们可以共享许多工具,而不管执行者是谁。例如,Flutter 应用性能和基础架构性能可能共享相同的仪表板和类似的警报机制。
扩大范围还允许包含传统上容易被忽视的执行者。文档性能就是一个例子。执行者可以是 SDK 的 API 文档,而指标可以是:发现 API 文档有用的读者百分比。
为什么性能很重要?
#回答这个问题不仅对于验证性能方面的工作至关重要,而且对于指导性能工作以使其更有用也至关重要。“为什么性能很重要?”的答案通常也是“性能如何有用?”的答案。
简单来说,性能很重要且有用,因为在相关范围内,性能必须具有可量化的属性或指标。这意味着:
- 性能报告易于理解。
- 性能几乎没有歧义。
- 性能可比且可转换。
- 性能公平。
并不是说非性能、不可衡量的问题或描述不重要。它们旨在突出性能可以更有用的场景。
1. 性能报告易于理解
#性能指标是数字。读取数字比阅读段落容易得多。例如,工程师可能需要 1 秒钟来理解 1 到 5 的性能评级。而阅读一篇 500 字的完整反馈摘要,可能需要同一位工程师至少 1 分钟。
如果有很多数字,很容易对其进行汇总或可视化以供快速理解。例如,可以通过直方图、平均值、分位数等快速理解数百万个数字。如果一个指标有数千个数据点,那么可以轻松绘制时间线来读取其趋势。
另一方面,拥有 n 个 500 字的文本几乎可以保证需要 n 倍的成本来理解这些文本。分析数千个历史描述,每个描述都有 500 字,将是一项艰巨的任务。
2. 性能几乎没有歧义
#将性能作为一组数字的另一个优点是其明确性。当你希望动画每帧性能达到 20 毫秒或 50 帧/秒时,数字的解释几乎没有不同。另一方面,用文字描述同一个动画,有人可能会说它很好,而另一些人可能会抱怨它不好。同样,同一个词或短语可能被不同的人以不同的方式解释。你可能认为还可以的帧率是 60 帧/秒,而另一些人可能认为它只有 30 帧/秒。
数字仍然可能存在噪声。例如,测得的每帧时间可能是该帧的真实计算时间,加上 CPU/GPU 在某些不相关工作上花费的随机时间(噪声)。因此,指标会有波动。尽管如此,数字的含义并没有歧义。而且,还有严谨的理论和测试工具来处理这种噪声。例如,你可以进行多次测量来估计随机变量的分布,或者通过 大数定律 取多次测量的平均值来消除噪声。
3. 性能可比且可转换
#性能数字不仅意义明确,而且比较也明确。例如,毫无疑问 5 大于 4。另一方面,要弄清楚“优秀”比“绝佳”好还是差,可能是主观的。同样,你能弄清楚“史诗级”是否比“传奇级”更好吗?实际上,在某些人的解释中,“远超预期”可能比“绝佳”更好。只有在定义将“远超预期”映射到 4,将“绝佳”映射到 5 后,它才会变得明确且可比。
数字还可以使用公式和函数轻松转换。例如,60 帧/秒可以转换为每帧 16.67 毫秒。一帧的渲染时间 x (ms) 可以转换为一个二进制指示符 isSmooth = [x <= 16] = (x <= 16 ? 1 :0)
。这种转换可以复合或链接,因此你可以使用单个测量值获得各种数量,而不会增加任何噪声或歧义。转换后的数量可以用于进一步的比较和理解。如果你处理的是自然语言,这种转换几乎是不可能的。
4. 性能公平
#如果问题依赖于冗长的词语来发现,那么那些更健谈(更愿意聊天或写作)的人,或者那些更接近开发团队、沟通带宽更大、聊天或面对面会议成本更低的人,就会获得不公平的优势。
通过拥有相同的指标来检测问题,无论用户距离多远或有多沉默,我们都可以公平地对待所有问题。反过来,这使我们能够专注于真正有更大影响的问题。
如何使性能变得有用
#以下从稍有不同的角度总结了此处讨论的 4 个要点:
使性能指标易于理解。不要让读者被大量数字(或文字)淹没。如果有很多数字,则尝试将其汇总为一小组数字(例如,将许多数字汇总为单个平均数字)。仅在数字发生显著变化时通知读者(例如,自动警报关于高峰或回归)。
使性能指标尽可能明确。定义数字使用的单位。精确描述数字的测量方式。使数字易于重现。当存在大量噪声时,尝试显示完整分布,或通过聚合许多有噪声的测量来尽可能消除噪声。
方便比较性能。例如,提供时间线以比较当前版本与旧版本。提供方法和工具将一个指标转换为另一个指标。例如,如果我们能将内存增加和帧率下降都转换为用户流失数量或以美元计的收入损失,那么我们就可以进行比较并做出明智的权衡。
使性能指标监控尽可能广泛的人群,以免任何人被落下。