Android Baseline Profiles笔记

8 阅读2分钟

image.png

1. 这个优化是做什么的

其实就是一种让App启动更快,滑动更流畅。原理是在你的工程里放一个配置文件,列出用户一打开就会用到的代码,系统在安装的时候把这些代码提前编译好。这样用户第一次打开就不用等JIT边跑边编译了。

支持Android7.0及以上,性能大概提升15% - 30%,低端机比较明显。

2. 他的编译方式有什么不同

常见的三种编译方式;

标题功能优点缺点
纯JIT边运行边编译节省空间第一次打开慢
全量AOT安装时编译所有代码启动快安装慢,体积大
Baseline Profile预编译热点代码兼顾了性能,安装效率与体积

3. Baseline实现具体步骤(Benchmark)

1.创建benchmark,模拟启动和生成baseline

可以通过创建benchmark实现。 创建StartupBenchmark类,模拟启动和首次的交互等。

为了对比差异数据,使用CompilationMode.None()表示使用JIT模式编译,用CompilationMode.Partial()表示使用baseline的方式,一会看查看测试数据。

//benchmark -> StartupBenchmark.kts
@RunWith(AndroidJUnit4::class)
class StartupBenchmark {
    @get:Rule
    val benchmarkRule = MacrobenchmarkRule()

    @Test
    fun startupCompilationNone() = startup(CompilationMode.None())

    @Test
    fun startupCompilationPartial() = startup(CompilationMode.Partial())

    fun startup(compilationMode: CompilationMode) = benchmarkRule.measureRepeated(
        packageName = "com.jettx.empty",
        metrics = listOf(StartupTimingMetric()),
        iterations = 5,
        compilationMode = compilationMode,
        startupMode = StartupMode.COLD
    ) {
        pressHome()
        startActivityAndWait()
    }
}
//benchmark -> BaselineProfileGenerator.kts
@RunWith(AndroidJUnit4::class)
class BaselineProfileGenerator {

    @get:Rule
    val baselineProfileRule = BaselineProfileRule()

    @Test
    fun generate() = baselineProfileRule.collect(
        packageName = "com.jettx.empty",
        includeInStartupProfile = true
    ) {
        // 定义关键用户旅程
        pressHome()
        startActivityAndWait()

        // 可添加滑动、点击等交互
        // val recyclerView = device.findObject(By.res("recycler_view"))
        // recyclerView.waitForExists(5000)
        // recyclerView.fling(androidx.test.uiautomator.Direction.DOWN)
    }
}

2. 运行生成

 ./gradlew :benchmark:AndroidTest -P android.testInstrumentationRunnerArguments.androidx.benchmark.enableRules=BaselineProfile  

我是在模拟器上运行的,建议在真机上运行,模拟器上运行需要配置支持。

//benchmark -> build.gradle
 defaultConfig 
 {
     testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "EMULATOR"
 }

生成后把 /benchmark/build/outputs/connected_android_test_additional_output/benchmark/connected/Pixel8Api34(AVD) - 14/BaselineProfileGenerator_generate-startup-prof.txt 重命名为baseline-prof.txt放入/app/src/main/目录中。

3. 编译打包App

查看生成后的APK会有合入的baseline

image.png

4. 测试运行StartupBenchmark

StartupBenchmark_startupCompilationPartial
timeToInitialDisplayMs   min 1,694.4,   median 1,873.2,   max 2,458.6
Traces: Iteration 0 1 2 3 4

Pixel8Api34(AVD) - 14 Tests 1/2 completed. (0 skipped) (0 failed)
Timed out waiting for process (com.jettx.empty) to appear on Pixel8Api34 [emulator-5554].
WARNING: Running on Emulator
Benchmark is running on an emulator, which is not representative of
real user devices. Use a physical device to benchmark. Emulator
benchmark improvements might not carry over to a real user's
experience (or even regress real device performance).

StartupBenchmark_startupCompilationNone
timeToInitialDisplayMs   min  1,593.7,   median  2,602.0,   max 51,479.6
Traces: Iteration 0 1 2 3 4

Finished 2 tests on Pixel8Api34(AVD) - 14

从median来看,优化了729ms。

5 .参考文件

developer.android.com/topic/perfo…