版权声明

凡未经作者授权,任何媒体、网站及个人不得转载、仿制、重制、改动、展示或运用部分或悉数的内容或服务。如果已转载,请自行删去。一同,咱们保存进一步追查相关行为主体的法律责任的权利。

2023 小酥肉不加辣,All rights reserved.

运用 Macrobenchmark 检验 Android 运用功用

什么是 Benchmark(基准检验)

基准检验(benchmarking)是一种测量和评价软件功用方针的活动。你可以在特定时刻(比方每次运用发布时)经过基准检验树立一个已知的功用水平,称为基准线。当系统的软件、硬件或更改代码等环境发生改变之后再进行一次基准检验以确定哪些改变对功用产生影响,然后有针对性的进行功用优化

什么是 Macrobenchmark

Macrobenchmark 是 Android 系统上对运用进行基准检验的库,可以直接针对在搭载 Android M (API 23) 或更高版别系统的设备上工作的运用编写发起和工作时功用检验。

Macrobenchmark vs Microbenchmark

虽然现有的 Microbenchmark 库答应直接对运用程序代码进行基准检验,但它是环绕测量 CPU 工作频率而规划的,并且会达到最佳功用(JIT,磁盘缓存)。

Macrobenchmark 则经过实践发起和翻滚运用程序来测量终端用户的体会,并且你可以操控检验的功用环境(例如指定发起方法是冷发起)。

Macrobenchmark Microbenchmark
函数 测量高等级进口点或交互(例如,activity 发起或列表翻滚) 测量各个函数
规模 对整个运用进行进程外检验 对 CPU 作业情况进行进程内检验
速度 迭代速度中等(或许超越 1 分钟) 迭代速度较快(通常不到 10 秒)
跟踪 效果包括功用分析轨迹 可选的方法采样和跟踪
最低 API 版别 23 14

编写 Macrobenchmarks

基准检验经过 Macrobenchmark 库中的MacrobenchmarkRuleJUnit4 规则 API 供给:

@RunWith(AndroidJUnit4::class)
class ExampleStartupBenchmark {
    @get:Rule
    val benchmarkRule = MacrobenchmarkRule()
    @Test
    fun startup() = benchmarkRule.measureRepeated(
        packageName = "com.example.macrobenchmark_codelab",
        metrics = listOf(StartupTimingMetric()),
        iterations = 5,
        startupMode = StartupMode.COLD,
    ) {
        pressHome()
        startActivityAndWait()
        val contentList = device.findObject(By.res("snack_list"))
        val searchCondition = Until.hasObject(By.res("snack_collection"))
        // Wait until a snack collection item within the list is rendered
        contentList.wait(searchCondition, 5_000)
    }
}

工作基准检验

像工作单元检验相同,可以有以下几种方法工作:

  1. 右键点击工作按钮,选择要工作的检验类或方法
    运用 Macrobenchmark 检验 Android 运用功用
  2. 运用gradle命令工作一切的检验
./gradlew :macrobenchmark:connectedCheck
  1. 单独工作指定的检验
./gradlew :macrobenchmark:connectedCheck -P android.testInstrumentationRunnerArguments.class=com.example.macrobenchmark_codelab.ExampleStartupBenchmark#startup

查看检验效果

工作成功之后,检验效果闪现在效果面板中。

运用 Macrobenchmark 检验 Android 运用功用

点击效果中的链接,翻开CPU Profiler可以查看更多具体的信息。

运用 Macrobenchmark 检验 Android 运用功用

当然,除了直接闪现到面板中,检验效果还会以JSON格式保存在文件中。这些文件位于build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/目录中。

运用 Macrobenchmark 检验 Android 运用功用

JSON文件中包括工作基准检验的设备信息及实践工作的基准检验的信息,如下:

{
    "context": {
        "build": {
            "brand": "Xiaomi",
            "device": "umi",
            "fingerprint": "Xiaomi/umi/umi:12/SKQ1.211006.001/V13.0.7.0.SJBCNXM:user/release-keys",
            "model": "Mi 10",
            "version": {
                "sdk": 31
            }
        },
        "cpuCoreCount": 8,
        "cpuLocked": false,
        "cpuMaxFreqHz": 2841600000,
        "memTotalBytes": 7980748800,
        "sustainedPerformanceModeEnabled": false
    },
    "benchmarks": [
        {
            "name": "startup",
            "params": {},
            "className": "com.example.macrobenchmark.ExampleStartupBenchmark",
            "totalRunTimeNs": 28672528896,
            "metrics": {
                "timeToFullDisplayMs": {
                    "minimum": 746.078958,
                    "maximum": 963.759896,
                    "median": 834.385312,
                    "runs": [
                        834.385312,
                        851.603906,
                        963.759896,
                        755.41651,
                        746.078958
                    ]
                },
                "timeToInitialDisplayMs": {
                    "minimum": 392.343438,
                    "maximum": 505.486927,
                    "median": 440.035989,
                    "runs": [
                        440.035989,
                        459.768281,
                        505.486927,
                        395.72776,
                        392.343438
                    ]
                }
            },
            "sampledMetrics": {},
            "warmupIterations": 0,
            "repeatIterations": 5,
            "thermalThrottleSleepSeconds": 0
        }
    ]
}

自定义基准

捕获方针

方针是从基准中提取的首要信息类型。可用选项包括StartupTimingMetricFrameTimingMetricTraceSectionMetric

CompilationMode

宏基准可以指定CompilationMode,用于定义应该将运用的多大部分从 DEX 字节码(APK 中的字节码格式)预编译为机器代码(类似于预编译的 C++)。

在 Android 7 及更高版别中,您可以自定义CompilationMode以影响设备上的预编译量,然后仿照不同等级的预先 (AOT) 编译或 JIT 缓存。分为3个等级,包括CompilationMode.FullCompilationMode.PartialCompilationMode.None

StartupMode

如需履行 activity 发起,您可以传递一种预定义的发起模式(COLDWARMHOT中的一种)。此参数会更改 activity 的发起方法,以及检验开始时的进程状态。

自定义工作

利用自定义跟踪工作进行运用插桩十分有用,这些工作会与跟踪陈述的其余部分一同闪现,有助于找出运用特有的问题。

以下示例代码展示列表闪现过程中自定义的创建视图和获取数据的工作:

class MyAdapter : RecyclerView.Adapter<MyViewHolder>() {
  override fun onCreateViewHolder(parent: ViewGroup,
      viewType: Int): MyViewHolder {
    trace("MyAdapter.onCreateViewHolder") {
      MyViewHolder.newInstance(parent)
    }
  }
  override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
    trace("MyAdapter.onBindViewHolder") {
      trace("MyAdapter.queryDatabase")
        val rowItem = queryDatabase(position)
        dataset.add(rowItem)
      }
      holder.bind(dataset[position])
    }
  }
}

更多相关文章

重视我的 Android 功用优化 专栏

Android Runtime – Dalvik 和 ART 是如何作业的?

运用 Baseline Profiles 改善 Android 运用功用

运用 Macrobenchmark 检验 Android 运用功用