美文网首页
Gfxinfo 衡量安卓UI的性能

Gfxinfo 衡量安卓UI的性能

作者: 爱睡觉的小章鱼 | 来源:发表于2020-06-02 14:10 被阅读0次

    用户界面(UI)性能测试不仅可以确保app满足其功能要求,而且能够保证用户与app之间的交互是相当平滑的——以每秒60帧的速度运行(为什么是60fps?),没有任何丢弃或延迟的帧(或者我们喜欢称之为jank)。本文档介绍了可用于衡量UI性能的工具,并提供了将UI性能测量集成到测试实践中的方法。

    为了提高性能,我们首先需要能够衡量系统的性能,然后诊断并识别可能从管道的各个部分到达的问题。

    dumpsys是一款运行在设备上的Android工具,可以输出有关系统服务状态的信息。将 gfxinfo命令传递给dumpsys可在logcat中提供输出,其中记录了各阶段期间发生的动画以及帧相关的性能信息。

    1.输入命令

    示例:adb shell dumpsys gfxinfo < PACKAGE_NAME >

    比如:adb shell dumpsys gfxinfo com.hashkey.hub

    会出现如下结果

    2.聚合帧统计信息

    Graphics info for pid 2040 [com.hashkey.hub]  -表明当前dump的为hashkey hub应用界面的帧信息,pid为2040

    Total frames rendered: 2240817  -本次dump搜集了2240817帧的信息

    Janky frames: 2163335 (96.54%)  -2240817帧中有2163335 帧的耗时超过了16ms,卡顿概率为96.54%

    50th percentile: 32ms

    90th percentile: 44ms

    95th percentile: 48ms

    99th percentile: 61ms

    Number Missed Vsync: 276985  -垂直同步失败的帧

    Number High input latency: 7  -处理input时间超时的帧数

    Number Slow UI thread: 1290744  -因UI线程上的工作导致超时的帧数

    Number Slow bitmap uploads: 150321  -因bitmap的加载耗时的帧数

    Number Slow issue draw commands: 2040376  -因绘制导致耗时的帧数

    HISTOGRAM: 5ms=8610 6ms=1886 7ms......直方图数据,表面耗时为0-5ms的帧数为8610,耗时为5-6ms的帧数为1886,同理类推。这些高级统计数据在很高的层次上向我们传达了app的渲染性能,以及它在许多帧中的稳定性。

    3.精确帧耗时信息

    Android 6.0版本为gfxinfo提供了一个新的命令——framestats,其作用是可以从最近的帧中获取非常详细的帧耗时信息,因此我们可以更准确地跟踪和调试问题。

    adb shell dumpsys gfxinfo com.hashkey.hub framestats >D:\zy.csv

    此命令会打印出来app最后生成的120帧的帧耗时信息(使用纳秒时间戳)。运行该命令后,可将结果写进D盘的zy.csv文件里面

    csv中各个字段的解释如下:

    Framestats数据格式

    由于数据块以CSV格式输出,因此将其粘贴到我们选择的电子表格工具,或者使用脚本进行收集和解析非常简单。下面说明了输出数据列的格式。所有时间戳都以纳秒为单位(1纳秒=1e-6毫秒)。

    1.FLAGS

    如果flags为0,则此帧的总耗时时间 = FRAME_COMPLETED(第14列,帧的结束时间) - INTENDED_VSYNC(第2列,帧的预期开始时间)。

    如果flags不为0,则忽略该行,因为该帧的布局和绘制时间超过16ms,为异常帧。以下是可能发生的一些原因:

    (1)窗口布局发生变化(例如app的第一帧或旋转后);

    (2)帧被跳过也是有可能的,在这种情况下,某些值将具有垃圾时间戳。例如,如果帧超出60fps,或者屏幕上没有任何内容变脏,则可能跳过一个帧,这不一定是app中出现问题的迹象。

    2.INTENDED_VSYNC

    帧的预期开始时间。如果此值与VSYNC不同,则UI线程上发生了阻止其及时响应vsync信号的工作。

    3.VSYNC

    花费在vsync监听器和帧绘制的时间(Choreographer frame回调,动画,View.getDrawingTime()等)。

    要了解VSYNC的更多信息及其对app的影响,请查看Understanding VSYNC视频。

    4.OLDEST_INPUT_EVENT

    输入队列中最早输入事件的时间戳。如果此帧没有输入事件,则为Long.MAX_VALUE。

    此值主要用于平台工作,对app开发人员的用处不大。

    5.NEWEST_INPUT_EVENT

    输入队列中最后输入事件的时间戳,如果此帧没有输入事件,则为0。

    此值主要用于平台工作,对app开发人员的用处不大。

    但是,通过计算FRAME_COMPLETED - NEWEST_INPUT_EVENT的值,可以大致了解app添加的延迟时间。

    6.HANDLE_INPUT_START

    将输入事件分派给app的时间戳。

    通过计算ANIMATION_START - HANDLE_INPUT_START的值,可以测量app处理输入事件所花费的时间。

    如果它们的时间差很高(> 2ms),则表示app花费了非常长的时间处理输入事件,例如View.onTouchEvent(),这可能表示此工作需要优化,或者分发到其他线程。但是请注意,在某些情况下,例如发起新活动或类似活动的点击事件时,预计可接受的时间差是很大的。

    7.ANIMATION_START

    运行Choreographer注册动画的时间戳。

    通过计算PERFORM_TRANVERSALS_START - ANIMATION_START的值,可以得到评估正在运行的所有动画器(ObjectAnimator,ViewPropertyAnimator和常用转换器)所花费的时间。

    如果它们的时间差很高(> 2ms),请检查您的app是否已编写了自定义动画或者设置了ObjectAnimators动画的字段,并确保它们适用于动画。

    要了解Choreographer的更多信息,请查看For Butter or Worse视频。

    8.PERFORM_TRAVERSALS_START

    计算DRAW_START - PERFORM_TRAVERSALS_START的值,可以得到完成布局和度量阶段所需的时间。(注意,在滚动或动画期间,你会希望它应该接近于零)

    要了解有关渲染管道的度量和布局阶段的更多信息,请查看Invalidations, Layouts and Performance视频。

    9.DRAW_START

    performTraversals的绘制阶段开始的时间戳。这是录制任何无效视图的显示列表的起点。

    此时间与SYNC_START之间的时间是在树中所有无效视图上调用View.draw()所需的时间。

    有关绘图模型的更多信息,请查看Hardware Acceleration或者Invalidations, Layouts and Performance视频。

    10.SYNC_QUEUED

    将同步请求发送到RenderThread的时间。

    这标志着开始同步阶段的消息被发送到RenderThread的时刻。如果此时间与SYNC_START之间的时间差很长(> 0.1ms左右),则表示RenderThread正忙于处理不同的帧。在内部,这用于区分执行太多工作以至于超过16ms预算的帧和由于前一帧超过16ms预算而导致被停止的帧。

    11.SYNC_START

    绘图同步阶段开始的时间。

    如果此时间与ISSUE_DRAW_COMMANDS_START之间的时间很长(> 0.4ms左右),则通常表示已绘制了许多必须上传到GPU的新位图。

    要了解有关同步阶段的更多信息,请查看Profile GPU Rendering视频。

    12.ISSUE_DRAW_COMMANDS_START

    硬件渲染器开始向GPU发出绘图命令的时间。

    计算FRAME_COMPLETED - ISSUE_DRAW_COMMANDS_START的值,可以大致了解app生成多少GPU工作。这里会出现很多过度绘制或低效的渲染效果等问题。

    13.SWAP_BUFFERS

    调用eglSwapBuffers的时间,在平台工作之外相对无用。

    14.FRAME_COMPLETED

    帧的结束时间戳。可以通过执行FRAME_COMPLETED - INTENDED_VSYNC来计算在此帧上工作的总时间。

    15.DequeueBufferDuration和QueueBufferDuration

    我测试的是Android 8.0版本,除了以上14列数据外,还有2列数据——DequeueBufferDuration和QueueBufferDuration,这2列数据在官方文档中没有提及,估计是后来新加的。

    相关文章

      网友评论

          本文标题:Gfxinfo 衡量安卓UI的性能

          本文链接:https://www.haomeiwen.com/subject/gslrzhtx.html