Macrobenchmark 使用之Baseline Profile 热点代码收集

2,976 阅读2分钟

这篇文章主要是为Android 启动优化,方案调研 的系统级别启动优化而记录的,在这篇文章中使用Baseline profile进行系统级别的优化方式可以说总共分为以下阶段:

  1. 热点代码收集(profile文件)
  2. 将profile文件写入系统

而这里介绍的就是如何手机应用的热点代码。

baseline profile的使用依赖于Macrobenchmark

有同学可能打不开官网,在这里对Baseline Profile 的使用做一个展示,并且利用现有的测试手机,提供一份简单的数据,用以验证Baseline Profile 在国内的可行性

一、创建项目

1.1、 创建一个正常的as项目

在项目application模块引入:

dependencies {
     implementation("androidx.profileinstaller:profileinstaller:1.2.0-beta01")
}

1.2 创建一个Macrobenchmark 项目,注意Android Studio 的版本必须最低是Bumblebee

  1. 右键新建module -> 选择Benchmark, 如图(target application 需要指定,这是需要测试的目标应用)

image.png

  1. 点击完成

1.3 设置应用

在目标应用AndroidManifest.xml 的中启用该功能

<profileable android:shell="true" />

为了能更好、更准确的使项目接近用户体验,直接将应用设置为不可以调试状态,开启混淆等操作,说白了就是release项目下进行测试

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
    benchmark {
        signingConfig signingConfigs.debug
        matchingFallbacks = ['release']
        debuggable false
    }
}

执行完此操作后,打开Build Vaeriants 应该处于这种状态:

image.png

在AS最新版本中,创建benchmark会自动执行以上操作,但最终目标就是上图所示为准。

二、使用

2.1 baseline profile 热点代码统计

  1. 代码
@OptIn(ExperimentalBaselineProfilesApi::class)
class TrivialBaselineProfileBenchmark {
    // [START baseline_profile_basic]
    @get:Rule
    val baselineProfileRule = BaselineProfileRule()

    @Test
    fun startup() = baselineProfileRule.collectBaselineProfile(
        packageName = "com.xxx.xxx",
        profileBlock = {
            startActivityAndWait()
            device.waitForIdle()
        }
    )
    // [END baseline_profile_basic]
}
  1. 运行完成之后,

image.png

  1. 使用如下代码导出:
adb pull storage/emulated/0/Android/media/com.example.app/SampleStartupBenchmark_startup-baseline-prof.txt .
  1. 将文件重命名为baseline-prof.txt并将其复制到应用的src/main目录中

这就完成了Baselineprofile 的热点代码统计

2.2 benchmark中的默认文件测试应用的启动速度(baselineprofile 启动速度优化 所以在上述的项目中添加以下代码,可以进行启动速度测试)

@RunWith(AndroidJUnit4::class)
class ExampleStartupBenchmark {
    @get:Rule
    val benchmarkRule = MacrobenchmarkRule()

    @Test
    fun startup() = benchmarkRule.measureRepeated(
        packageName = "com.kpa.baselineprofile",
        metrics = listOf(StartupTimingMetric()),
        iterations = 5,
        startupMode = StartupMode.COLD
    ) {
        pressHome()
        startActivityAndWait()
    }
}

指定包名,运行satrtup 就能得到某部手机的制定启动方式的最小启动时间、平均启动时间、最大启动时间, 如下图: image.png

还会在benchmark项目中生成网页报告

image.png

image.png