配置基准配置文件生成

使用基准配置文件 Gradle 插件,可以更轻松地生成和维护基准配置文件。它可帮助您执行以下任务:

本页介绍了如何使用基准配置文件 Gradle 插件自定义基准配置文件的生成。

插件要求

使用 Gradle 管理的设备生成基准配置文件

如需使用 Gradle 管理的设备 (GMD) 生成基准配置文件,请在配置文件生产方模块的 build.gradle.kts 配置中添加一个(可能是 :baselineprofile 测试模块),如以下示例所示:

Kotlin

android {
   testOptions.managedDevices.devices {
       create<com.android.build.api.dsl.ManagedVirtualDevice>("pixel6Api31") {
           device = "Pixel 6"
           apiLevel = 31
           systemImageSource = "aosp"
       }
   }
}

Groovy

android {
   testOptions.managedDevices.devices {
       pixel6Api31(ManagedVirtualDevice) {
           device 'Pixel 6'
           apiLevel = 31
           systemImageSource 'aosp'
       }
   }
}

通过将 GMD 添加到基准配置文件 Gradle 插件配置(在 :baselineprofile 测试模块的 build.gradle.kts 中),使用 GMD 生成基准配置文件,如下所示:

Kotlin

baselineProfile {
    managedDevices += "pixel6Api31"
}

Groovy

baselineProfile {
    managedDevices = ['pixel6Api31']
}

使用 GMD 生成基准配置文件时,请将 useConnectedDevices 设为 false,在 :baselineprofile 测试模块中执行以下操作:

Kotlin

baselineProfile {
    ...
    useConnectedDevices = false
}

Groovy

baselineProfile {
    ...
    useConnectedDevices false
}

为不同的变体生成基准配置文件

您可按变体、按变种生成基准配置文件,也可生成单个文件以用于所有变体。您可以通过合并设置控制此行为,例如 在以下示例的 build.gradle.kts 中, 应用或库模块

Kotlin

baselineProfile {
    mergeIntoMain = true
}

Groovy

baselineProfile {
    mergeIntoMain true
}

如需将为所有变体生成的配置文件合并到单个配置文件中,请将 mergeIntoMain 设为 true。当此设置设为 true 时,无法为每个变体生成基准配置文件,因此会有一个名为 generateBaselineProfile 的 Gradle 任务。该配置文件会在 src/main/generated/baselineProfiles 中输出。

如需停用合并功能并让每个变体都有一个配置文件,请将 mergeIntoMain 设为 false。在这种情况下,存在多个特定于变体的 Gradle 任务。举个例子,当有两个变种(比如免费和付费变种)和一个发布 build 类型时,任务如下所示:

* `generateFreeReleaseBaselineProfile`
* `generatePaidReleaseBaselineProfile`
* `generateReleaseBaselineProfile`

如需按变体指定合并行为,请使用以下代码:

Kotlin

baselineProfile {
    variants {
        freeRelease {
            mergeIntoMain = true
        }
    }
}

Groovy

baselineProfile {
    variants {
        freeRelease {
            mergeIntoMain true
        }
    }
}

在上面的示例中,标志设为 true 的所有变体都会合并到 src/main/generated/baselineProfiles 中,而标志设为 false 的变体对应的配置文件会保留在文件夹 src/<variant>/generated/baselineProfiles 中。

默认情况下,对于库,mergeIntoMain 设为 true;对于应用,则设为 false

在组装新版本时自动生成基准配置文件

您可将基准配置文件配置为随每个发布 build 自动生成,而不是使用任务 generateBaselineProfile 手动生成。如果自动生成配置文件,则最新的配置文件会包含在发布 build 中。

如需为发布 build 启用自动生成功能,请使用 automaticGenerationDuringBuild 标志:

Kotlin

baselineProfile {
    automaticGenerationDuringBuild = true
}

Groovy

baselineProfile {
    automaticGenerationDuringBuild true
}

automaticGenerationDuringBuild 标志设成 true 会为每个版本组件生成新的基准配置文件。这意味着,运行发布 build 组装任务(例如 ./gradlew:app:assembleRelease)也会触发 :app:generateReleaseBaselineProfile、启动基准配置文件插桩测试,并构建运行这些测试的基准配置文件 build。虽然自动生成方式有助于确保用户获得最佳性能优势,但由于需要进行双重构建和插桩测试,这也会增加构建时间。

您还可以按变体指定此行为,如以下示例所示:

Kotlin

baselineProfile {
    variants {
        freeRelease {
            automaticGenerationDuringBuild = true
        }
    }
}

Groovy

baselineProfile {
    variants {
        freeRelease {
            automaticGenerationDuringBuild true
        }
    }
}

在前面的示例中,generateFreeReleaseBaselineProfile 任务会在开始 assembleFreeRelease 时运行。这有时会很有帮助,比如在以下情况下:用户想有一个针对分发 build 的 release(始终会在构建时生成配置文件),和一个针对内部测试的 releaseWithoutProfile

将基准配置文件存储到源目录中

您可以通过 saveInSrc 将基准配置文件存储在源目录中 标志(在应用或库模块的 build.gradle.kts 中):

  • true:基准配置文件存储在 src/<variant>/generated/baselineProfiles 中。这样,您就可以使用源目录提交最新生成的配置文件。
  • false:基准配置文件存储在 build 目录下的中间文件中。这样,您在提交代码时不会保存最新生成的配置文件。

Kotlin

baselineProfile {
    saveInSrc = true
}

Groovy

baselineProfile {
    saveInSrc true
}

您还可以按变体指定此行为:

Kotlin

baselineProfile {
    variants {
        freeRelease {
            saveInSrc = true
        }
    }
}

Groovy

baselineProfile {
    variants {
        freeRelease {
            saveInSrc true
        }
    }
}

过滤配置文件规则

借助基准配置文件 Gradle 插件,您可以过滤生成的基准配置文件规则。如果您想为示例应用或库自身的其他依赖项中的类和方法排除配置文件规则,上述过滤对库特别有帮助。此过滤可以包含和排除特定软件包和类。当您仅指定排除项时,系统仅会排除匹配的基准配置文件规则,所有其他规则都会被包含在内。

过滤条件规范可以是以下任意一种:

  • 以双通配符结尾的软件包名称,与指定的软件包和所有子软件包匹配。例如,com.example.**com.example.methodcom.example.method.bar 匹配。
  • 以通配符结尾的软件包名称,仅与指定的软件包匹配。例如,com.example.*com.example.method 匹配,但与 com.example.method.bar 不匹配。
  • 匹配特定类(例如 com.example.MyClass)的类名称。

以下示例展示了如何包含和排除特定软件包:

Kotlin

baselineProfile {
    filter {
        include("com.somelibrary.widget.grid.**")
        exclude("com.somelibrary.widget.grid.debug.**")
        include("com.somelibrary.widget.list.**")
        exclude("com.somelibrary.widget.list.debug.**")
        include("com.somelibrary.widget.text.**")
        exclude("com.somelibrary.widget.text.debug.**")
    }
}

Groovy

baselineProfile {
    filter {
        include 'com.somelibrary.widget.grid.**'
        exclude 'com.somelibrary.widget.grid.debug.**'
        include 'com.somelibrary.widget.list.**'
        exclude 'com.somelibrary.widget.list.debug.**'
        include 'com.somelibrary.widget.text.**'
        exclude 'com.somelibrary.widget.text.debug.**'
    }
}

按如下方式为不同变体自定义过滤规则:

Kotlin

// Non-specific filters applied to all the variants.
baselineProfile {
    filter { include("com.myapp.**") }
}

// Flavor-specific filters.
baselineProfile {
    variants {
        free {
            filter {
                include("com.myapp.free.**")
            }
        }
        paid {
            filter {
                include("com.myapp.paid.**")
            }
        }
    }
}

// Build-type-specific filters.
baselineProfile {
    variants {
        release {
            filter {
                include("com.myapp.**")
            }
        }
    }
}

// Variant-specific filters.
baselineProfile {
    variants {
        freeRelease {
            filter {
                include("com.myapp.**")
            }
        }
    }
}

Groovy

// Non-specific filters applied to all the variants.
baselineProfile {
    filter { include 'com.myapp.**' }
}

// Flavor-specific filters.
baselineProfile {
    variants {
        free {
            filter {
                include 'com.myapp.free.**'
            }
        }
        paid {
            filter {
                include 'com.myapp.paid.**'
            }
        }
    }
}

// Build-type specific filters.
baselineProfile {
    variants {
        release {
            filter {
                include 'com.myapp.**'
            }
        }
    }
}

// Variant-specific filters.
baselineProfile {
    variants {
        freeRelease {
            filter {
                include 'com.myapp.**'
            }
        }
    }
}

您还可以在 BaselineProfileRule.collect() 中使用 filterPredicate 参数来过滤规则,但我们建议您使用 Gradle 插件进行过滤,因为这种方法可让您更轻松地过滤子软件包以及在同一位置配置整个模块。

自定义基准和基准配置文件 build 类型

基准配置文件 Gradle 插件会创建其他 build 类型以生成 以及运行基准测试这些 build 类型的前缀为 benchmarknonMinified。例如,对于 release build 类型, 插件会创建 benchmarkReleasenonMinifiedRelease build 类型。 这些 build 类型会自动配置为特定用例,通常不需要任何自定义。但在某些情况下 应用一些自定义选项可能仍然很有用,例如 不同的签名配置。

您可以使用 build 类型属性;就会被覆盖 以下示例展示了如何自定义其他 build 类型和 哪些属性会被替换:

Kotlin

android {
    buildTypes {
        release {
            ...
        }
        create("benchmarkRelease") {
            // Customize properties for the `benchmarkRelease` build type here.
            // For example, you can change the signing config (by default
            // it's the same as for the `release` build type).
            signingConfig = signingConfigs.getByName("benchmarkRelease")
        }
        create("nonMinifiedRelease") {
            // Customize properties for the `nonMinifiedRelease` build type here.
            signingConfig = signingConfigs.getByName("nonMinifiedRelease")

            // From Baseline Profile Gradle plugin 1.2.4 and higher, you can't
            // customize the following properties, which are always overridden to
            // avoid breaking Baseline Profile generation:
            //
            // isJniDebuggable = false
            // isDebuggable = false
            // isMinifyEnabled = false
            // isShrinkResources = false
            // isProfileable = true
            // enableAndroidTestCoverage = false
            // enableUnitTestCoverage = false
        }
    }
}

Groovy

android {
    buildTypes {
        release {
            ...
        }
        benchmarkRelease {
            // Customize properties for the `benchmarkRelease` build type here.
            // For example, you can change the signing config (by default it's the
            // same as for the `release` build type.)
            signingConfig = signingConfigs.benchmarkRelease
        }
        nonMinifiedRelease {
            // Customize properties for the `nonMinifiedRelease` build type here.
            signingConfig = signingConfigs.nonMinifiedRelease

            // From Baseline Profile Gradle plugin 1.2.4 and higher, you can't use
            // the following properties, which are always overridden to avoid breaking
            // Baseline Profile generation:
            //
            // isJniDebuggable = false
            // isDebuggable = false
            // isMinifyEnabled = false
            // isShrinkResources = false
            // isProfileable = true
            // enableAndroidTestCoverage = false
            // enableUnitTestCoverage = false       
        }
    }
}

其他说明

创建基准配置文件时,还需要注意一些其他事项:

  • 已编译的基准配置文件必须小于 1.5 MB。此规则不适用于源文件中的文本格式,源文件在编译之前通常会比 1.5 MB 大出很多。如需验证二进制基准配置文件的大小,请在输出工件中找到相应文件(APK:位于 assets/dexopt/baseline.prof 下;AAB:位于 BUNDLE-METADATA/com.android.tools.build.profiles/baseline.prof 下)。

  • 如果宽泛规则对应用编译过多,就会增加磁盘访问,进而降低启动速度。如果您刚开始使用基准配置文件,无需担心。不过,添加大量历程可能会导致性能不够理想,具体取决于您的应用以及历程的大小和数量。请尝试通过使用不同的配置文件和确认新增历程不会导致性能降低来测试性能。

Codelab

深入探究宏基准测试来衡量性能。
为具体 Android 应用生成量身定制的自定义基准配置文件,并验证其有效性。