一、性能基准测试概述
1.1 什么是性能基准测试
说白了,性能基准测试就是给App「量体温、测血压」。你想想看,没有数据你根本不知道App跑得快还是慢,耗电多还是少。我用一句大白话总结:用可重复、可量化的方法,测量App在特定场景下的关键性能指标。
我个人习惯把基准测试分成两类:
- 微基准测试:测量单个函数或组件的性能,比如方法耗时、循环效率。
- 宏观基准测试:测量整个应用或场景的综合表现,比如启动时间、页面的流畅度。
举个例子,我曾经在一个社交App里做过一个微基准测试——对比Gson和Moshi解析同一个JSON的速度。结果出来,Moshi快了将近3倍,直接换库,App启动冷启动减少了200ms。这就是基准测试的价值所在。
核心观点: 没有基准测试,优化就是瞎子摸象。你改代码前必须知道基线在哪,改完后再跑一遍,对比数据,才能说有没有效果。
1.2 为什么需要做基准测试
我给你列三个最直接的理由:
- 量化目标:你说「启动要优化」,那到底从3秒优化到2秒,还是1.5秒?没有基线就没法定KPI。
- 防止回归:我遇到过好几次,新功能上线后屏幕滑动变卡了——一看,是同事在列表滑动时做了个重量级计算。如果有基准测试流水线,这种问题在CI阶段就能被发现。
- 选型依据:框架、图片库、序列化库……技术选型不能光看文档,得跑一把数据说话。
我记得有一次项目大版本重构,之前没有建立任何性能基线。上线后用户反馈「比以前卡」,但我们完全拿不出数据反驳,也没法快速定位。从那以后,我坚持每个版本都跑一遍核心场景基准测试,并把趋势图挂在团队看板上。
1.3 常见性能指标
下面这张表整理了Android性能测试中最常见的6类指标,每个我都踩过坑。
| 指标 | 含义 | 测量工具 | 我的避坑经验 |
|---|---|---|---|
| CPU | App占用的CPU时间/负载,单位%或ms | adb shell top, Profiler | 不要只看瞬时值,要取30s以上的平均值;注意多核的换算 |
| 内存 | PSS、Java Heap、Native Heap、Graphics等 | adb shell dumpsys meminfo, LeakCanary | 我曾经遇到过内存泄漏在压测10分钟后才暴露,所以常规测试至少要跑15分钟 |
| GPU | 渲染时长、掉帧数、jank(卡顿帧) | GPU Profiler, Systrace, Perfetto | 掉帧率比平均帧率更重要,超过阈值(比如3ms)才是真正的卡顿 |
| 网络 | 请求耗时、吞吐量、错误率、DNS解析时间 | Charles, Network Profiler, OkHttp日志 | 我习惯在弱网环境下(3G/丢包)也跑基准,很多线上问题就是在弱网下才暴露 |
| 启动时间 | 冷启动、温启动、热启动的完成时间 | adb logcat -s ActivityManager, 手动记录 | 冷启动至少测5次取中位数,前几次有系统预热效应;第一次启动数据往往偏高 |
| 功耗 | 电池消耗曲线,单位mAh或% | Battery Historian, Profiler能耗面板 | 功耗与亮屏、CPU频率、网络信号强相关,尽量在同一环境下(固定亮度、关闭后台同步)测试 |
一点小建议: 别一次性测所有指标,挑跟你当前任务最相关的2~3个先建立基线。比如你在做启动优化,就先盯住启动时间和CPU初始化峰值;做列表优化,就盯住GPU掉帧数和内存分配。
1.4 基准测试的核心挑战
你可能会觉得「不就是跑个分嘛」,但实际落地的时候,坑多得让你怀疑人生。
- 环境不一致:同一台手机,插电和不插电CPU频率不同;后台App不同,数据也不同。我的做法是用脚本统一关闭所有非必要服务,设置性能模式固定频率。
- 数据波动大:即使同一台机器、同一段时间跑5次,结果也可能差20%。这时候我会用中位数或90%分位数,去掉异常最大值。
- 可重复性差:有些问题需要特定操作序列才会复现,比如先滑动再点击再返回。我会把测试步骤写成自动化脚本,用UI Automator或Espresso驱动。
嗯,这里要注意一点:千万不要拿一台工程机(root过、装了很多测试工具的手机)来做基准测试。它的性能可能比用户手机好很多,或者因为后台服务拖累反而更差。我吃过这个亏,跑出来的数据在公司手机和用户手机之间完全对不上。
警告: 基准测试数据只对你自己当时的测试环境有效。不要在汇报时把「小米10 Pro在测试环境下CPU占用15%」直接说成「App CPU占用15%」,一定要注明机型、系统版本、测试条件。否则面试官或Leader会直接质疑你的专业度。
1.5 如何开始你的第一次基准测试
别想得太复杂,第一次就选一个最简单的场景:测量App冷启动时间。我带你走一遍流程:
- 清理后台进程,保证手机没有其他App运行。
- 打开终端,输入:
adb logcat -c # 清空日志 adb shell am start -W -n com.yourapp/.MainActivity # 启动App - 在Logcat中查找
Displayed com.yourapp/.MainActivity: +2s123ms,记录这个时间。 - 重复以上步骤5次,去掉最大和最小值,取中间3次的平均值。
- 把这个数字记下来,作为你的基线。
你看,就这么简单。关键是要坚持重复和记录。很多老项目之所以性能越来越差,就是因为没人回头看一眼基线。我今天就希望你从这个最简单的命令开始,养成「先测再改」的好习惯。