App 卡顿别靠猜,仓颉自带的性能分析工具该上场了
App 一卡,很多人的第一反应是猜:是不是这个循环写得不好?是不是那个列表渲染慢?然后凭感觉东改一处、西改一处,改完发现还是卡,白忙活半天。靠猜来优化性能,方向全凭运气,效率极低。
其实华为仓颉编程语言自带了一个专门的性能分析工具,叫 `cjprof`。它能告诉你 CPU 的时间到底花在了哪个函数上、内存到底被谁占着,让你拿着数据去优化,而不是拍脑袋。这篇就带你认识它,学会用数据定位卡顿。
先认识 cjprof:它是干什么的
`cjprof` 的全称是 Cangjie Profile,是仓颉语言官方的性能分析工具。它主要做三件事:对程序的 CPU 热点函数采样、把采样数据分析成报告或火焰图、导出并分析堆内存。
cjprof [--help] COMMAND [ARGS] record采集 CPU 热点函数信息 report生成热点函数报告(含火焰图) heap导出和分析堆内存
说白了,CPU 为什么忙、内存被谁吃掉,这两个性能上最常见的问题,它都能帮你查清楚。需要说明的是,`cjprof` 目前在 Linux 系统上提供这些分析能力。下面按使用顺序,一步步看怎么用它。

第一步:record,先把现场采下来
要分析性能,先得有数据。`cjprof record` 负责采样,它会在程序运行时,按一定频率不断记录此刻 CPU 正在执行哪个函数。
# 对正在运行的进程(进程号 12345)采样,结果存到 sample.data cjprof record -f 10000 -p 12345 -o sample.data
`-p` 指定要采样的进程号,`-f` 指定采样频率,默认 5000 赫兹,也就是每秒采五千次。采样会一直进行,直到程序退出,或者你按 `Ctrl+C` 主动停止。这一步的产物是一个数据文件,相当于把卡顿现场完整地录了下来,供下一步分析。
第二步:report,把数据变成能看懂的报告
光有采样数据还看不出名堂,得用 `cjprof report` 把它分析成人能读的报告。
# 分析 sample.data,生成文本报告 cjprof report -i sample.data
默认生成的是文本报告,它把每个函数的采样占比从高到低排出来。占比越高的函数,说明 CPU 在它身上花的时间越多,那它就是头号优化嫌疑对象。你不用再猜哪里慢了,报告会直接把最耗时的函数排在最上面给你看。
第三步:火焰图,一眼看出谁最耗时
文本报告之外,`cjprof` 还能生成火焰图,这是定位热点最直观的方式。加一个 `-F` 选项就行。
# 生成火焰图,存为 test.svg cjprof report -F -o test.svg
火焰图怎么看?记住两条:横轴代表采样占比,一个函数的格子越宽,说明它越耗时;纵轴代表调用栈,下面是父函数、上面是它调用的子函数。所以你一眼扫过去,找那个最宽的格子,卡顿的元凶通常就在那。这比一行行读文本报告快得多。

还能查内存:heap 子命令
卡顿不只是 CPU 的事,内存占用过高同样会让 App 变慢。`cjprof` 的 `heap` 子命令,专门用来导出和分析堆内存。
cjprof heap# 导出堆内存并分析
当你怀疑 App 占内存过多、或者内存一直涨不下来时,就用它把堆内存导出来,看看到底是哪些东西占着不放。CPU 和内存这两条线都能查,性能问题基本就没有死角了。

权限提醒:record 需要 perf 权限
有一个实际的小细节要提前知道:`cjprof record` 依赖系统的 perf 权限,否则可能采不到数据。
满足下面任一条件即可:用 `root` 用户或 `sudo` 执行,或者把系统的 `perf_event_paranoid` 参数设为 -1。第一次用 record 采不到数据,多半就是权限没到位,先检查这里,能省下不少排查时间。
用数据说话,优化才有方向
总结一下这套流程:`record` 把卡顿现场采下来,`report` 把数据变成报告,火焰图让你一眼看出最耗时的函数,`heap` 再帮你把内存问题也兜住。整套下来,你优化性能就有了实打实的依据。

性能优化最忌讳的就是凭感觉瞎改。把 `cjprof` 用起来,让数据告诉你该优化哪里,你的每一次改动才真正改在刀刃上。工具用对了,卡顿就不再是玄学。

夜雨聆风