撰寫 Macrobenchmark

使用 Macrobenchmark 程式庫測試應用程式的大型用途,包括應用程式啟動及複雜的 UI 操控方式,例如捲動 RecyclerView 或執行動畫。如要測試程式碼較小的區域,請參閱 Microbenchmark 程式庫

程式庫會將基準測試結果輸出至 Android Studio 主控台和 JSON 檔案,並納入更多詳細資料。這個程式庫也提供追蹤檔,您可以在 Android Studio 中載入並分析這些追蹤檔。

請參閱「在持續整合中執行基準測試」,瞭解如何在持續整合 (CI) 環境中使用 Macrobenchmark 程式庫。

您可以使用 Macrobenchmark 產生基準設定檔。請按照以下指南設定 Marcobenchmark 程式庫,然後建立基準設定檔

專案設定

建議您將 Macrobenchmark 與最新版的 Android Studio 搭配使用,因為該 IDE 版本中的新功能已與 Macrobenchmark 整合。

設定 Macrobenchmark 模組

Macrobenchmark 需要獨立於應用程式程式碼之外的 com.android.test 模組,負責執行評估應用程式的測試。

您可以在 Android Studio 中使用範本來簡化 Macrobenchmark 模組設定。基準測試模組範本會在專案中自動建立模組,以評估由應用程式模組建立的應用程式,包括基準測試啟動範例。

如要使用模組範本建立新模組,請執行下列步驟:

  1. 在 Android Studio 的「Project」面板中,於專案或模組上按一下滑鼠右鍵,然後依序點選「New」>「Module」

  2. 從「Templates」 窗格中選取「Benchmark」

  3. 您可以自訂目標應用程式 (要進行基準測試的應用程式) 以及新的 Macrobenchmark 模組的套件和模組名稱。

  4. 按一下「Finish」

基準測試模組範本

設定應用程式

如要對應用程式進行基準測試 (稱為 Marcobenchmark 的「目標」),應用程式必須為 profileable,以便在不影響效能的情況下讀取詳細的追蹤記錄資訊。模組精靈會將 <profileable> 標記自動新增至應用程式的 AndroidManifest.xml 檔案。

盡可能將基準測試應用程式設定為接近發布版本 (或正式版)。為提升效能,請將應用程式設為無法進行偵錯,並建議開啟壓縮功能。您通常只需建立發布變化版本的副本即可,這個副本會以相同方式運作,但以偵錯金鑰在本機簽署。您也可以使用 initWith 指示 Gradle 進行以下操作:

Groovy

buildTypes {
    val release = getByName("release") {
        isMinifyEnabled = true
        isShrinkResources = true
        proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
    }

    create("benchmark") {
        initWith(release)
        signingConfig = signingConfigs.getByName("debug")
        proguardFiles("benchmark-rules.pro")
    }
}

Kotlin

buildTypes {
    getByName("release") {
        isMinifyEnabled = true
        isShrinkResources = true
        proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"))
    }

    create("benchmark") {
        initWith(getByName("release"))
        signingConfig = signingConfigs.getByName("debug")
    }
}

執行 Gradle 同步處理作業,開啟左側的「Build Variants」面板,然後選取應用程式和 Macrobenchmark 模組的基準測試變化版本。這可確保基準測試執行作業會建構及測試正確的應用程式變化版本:

選取基準測試變化版本

(選用) 設定多模組應用程式

如果您的應用程式有多個 Gradle 模組,您必須確保建構指令碼知道要編譯哪個建構變化版本。在未設定的情況下,新增的 benchmark buildType 會導致建構失敗,並顯示下列錯誤訊息:

> Could not resolve project :shared.
     Required by:
         project :app
      > No matching variant of project :shared was found.
      ...

如要解決這個問題,請將 matchingFallbacks 屬性添加至 :macrobenchmark:app 模組的 benchmark buildType 中。其餘 Gradle 模組的設定可與之前相同。

Groovy

benchmark {
    initWith buildTypes.release
    signingConfig signingConfigs.debug

    matchingFallbacks = ['release']
}

Kotlin

create("benchmark") {
    initWith(getByName("release"))
    signingConfig = signingConfigs.getByName("debug")

    matchingFallbacks += listOf('release')
}

在專案中選取建構變化版本時,請為 :app:macrobenchmark 模組選擇 benchmark,如為應用程式中的任何其他模組,請選擇 release,如下圖所示:

多模組專案的基準測試變化版本,且已選取版本和基準測試 buildType

詳情請參閱變化版本感知依附元件管理

(選用) 設定變種版本

如果應用程式中設定了多個變種版本,您必須設定 :macrobenchmark 模組,以便系統知道要建構和進行基準測試的應用程式變種版本。如果沒有進行這項設定,您可能會收到類似使用多個 Gradle 模組的建構錯誤:

Could not determine the dependencies of task ':macrobenchmark:connectedBenchmarkAndroidTest'.
> Could not determine the dependencies of null.
   > Could not resolve all task dependencies for configuration ':macrobenchmark:benchmarkTestedApks'.
      > Could not resolve project :app.
        Required by:
            project :macrobenchmark
         > The consumer was configured to find a runtime of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'benchmark', attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '7.3.0'. However we cannot choose between the following variants of project :app:
             - demoBenchmarkRuntimeElements
             - productionBenchmarkRuntimeElements
           All of them match the consumer attributes:
           ...

本指南會在 :app 模組中使用兩個變種版本:demoproduction。如以下程式碼片段所示:

Groovy

flavorDimensions 'environment'
productFlavors {
    demo {
        dimension 'environment'
        // ...
    }

    production {
        dimension 'environment'
        // ...
    }
}

Kotlin

flavorDimensions += "environment"
productFlavors {
    create("demo") {
        dimension = "environment"
        // ...
    }
    create("production") {
        dimension = "environment"
        // ...
    }
}

有兩種方法可以設定多個變種版本的基準測試:

使用 missingDimensionStrategy

:macrobenchmark 模組的 defaultConfig 中指定 missingDimensionStrategy,會指示建構系統改回使用版本維度。如果在模組中未找到這些維度,您必須指定要使用的維度。在以下範例中,系統會使用 production 變種版本做為預設維度:

Groovy

defaultConfig {
    missingDimensionStrategy "environment", "production"
}

Kotlin

defaultConfig {
    missingDimensionStrategy("environment", "production")
}

這樣一來,:macrobenchmark 模組只能建構指定的變種版本並進行基準測試,而知道只有一個變種版本有適當設定能進行基準測試,對您相當實用。

:macrobenchmark 模組中定義變種版本

如要建構其他變種版本並進行基準測試,您必須在 :macrobenchmark 模組中定義變種版本。指定方式與 :app 模組中相似,但僅需將 productFlavors 指派給 dimension,無需進行其他設定:

Groovy

flavorDimensions 'environment'
productFlavors {
    demo {
        dimension 'environment'
    }

    production {
        dimension 'environment'
    }
}

Kotlin

flavorDimensions += "environment"
productFlavors {
    create("demo") {
        dimension = "environment"
    }
    create("production") {
        dimension = "environment"
    }
}

定義並同步處理專案後,從「Build Variants」窗格中選擇所需的建構變化版本:

專案的基準測試變化版本,已選取顯示 productionBenchmark 的變種版本和版本

詳情請參閱解決與變化版本比對相關的建構錯誤一文。

建立 Macrobenchmark 類別

基準測試是透過 Macrobenchmark 程式庫中的 MacrobenchmarkRule JUnit4 規則 API 提供。其中包含 measureRepeated 方法,讓您指定關於如何執行目標應用程式並進行基準測試的各種條件。

您必須指定目標應用程式的 packageName、要評估的 metrics,以及有多少 iterations 應執行基準測試。

Kotlin

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

    @Test
    fun startup() = benchmarkRule.measureRepeated(
        packageName = TARGET_PACKAGE,
        metrics = listOf(StartupTimingMetric()),
        iterations = DEFAULT_ITERATIONS,
        setupBlock = {
            // Press home button before each run to ensure the starting activity isn't visible.
            pressHome()
        }
    ) {
        // starts default launch activity
        startActivityAndWait()
    }
}

Java

@LargeTest
@RunWith(AndroidJUnit4.class)
public class SampleStartupBenchmark {
    @Rule
    public MacrobenchmarkRule benchmarkRule = new MacrobenchmarkRule();

    @Test
    public void startup() {
        benchmarkRule.measureRepeated(
            /* packageName */ TARGET_PACKAGE,
            /* metrics */ Arrays.asList(new StartupTimingMetric()),
            /* iterations */ 5,
            /* measureBlock */ scope -> {
                // starts default launch activity
                scope.startActivityAndWait();
                return Unit.INSTANCE;
            }
        );
    }
}

如要瞭解自訂基準測試的所有選項,請參閱「自訂基準測試」一節。

執行基準測試

在 Android Studio 中執行測試,可測量應用程式在裝置上的效能。您可以執行基準測試,方式與您使用測試類別或方法旁的空白邊動作執行其他 @Test 時相同,如下圖所示。

使用測試類別旁的空白邊動作執行 Macrobenchmark

您也可以透過執行 ConnectedCheck 指令,在指令列執行 Gradle 模組中的所有基準測試:

./gradlew :macrobenchmark:connectedCheck

或執行單一測試:

./gradlew :macrobenchmark:connectedCheck -P android.testInstrumentationRunnerArguments.class=com.example.macrobenchmark.startup.SampleStartupBenchmark#startup

如要瞭解如何在持續整合服務中執行及監控基準測試,請參閱「在 CI 中執行基準測試」一節。

基準測試結果

基準測試執行完畢後,指標會直接顯示在 Android Studio 中,也會在 JSON 檔案中列為 CI 使用情形的輸出內容。每項經過評估的疊代作業都會擷取個別系統追蹤記錄。如要開啟結果追蹤記錄,請按一下「Test Results」窗格中的任一連結,如下圖所示。

Macrobenchmark 啟動結果

載入追蹤記錄時,Android Studio 會提示您選取要分析的程序。應用程式會預先填入目標應用程式程序:

選取工作室追蹤程序

追蹤檔載入完成後,Studio 會在 CPU 分析器工具中顯示結果:

Studio 追蹤記錄

JSON 報表和所有剖析追蹤記錄也會自動從裝置複製到主機。寫入主體機器的位置如下:

project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/

手動存取追蹤檔

如果您想使用 Perfetto 工具分析追蹤檔,還需要執行其他步驟。Perfetto 可讓您查看在追蹤記錄期間裝置上透過裝置處理的所有程序,而 Android Studio 的 CPU 分析器會將檢查限制為單一程序。

如果您從 Android Studio 叫用測試或使用 Gradle 指令列,追蹤檔會自動從裝置複製到主機。這些程式碼會在主機機器上寫入:

project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/TrivialStartupBenchmark_startup[mode=COLD]_iter002.perfetto-trace

在主機系統上取得追蹤檔後,在選單中依序點選「File」>「Open」,即可透過 Android Studio 開啟追蹤檔。如上節所示的分析器工具檢視畫面。

設定錯誤

如果應用程式設定錯誤 (可進行偵錯或無法剖析),Macrobenchmark 會傳回錯誤,而不是回報不正確或不完整的測量結果。您可以使用 androidx.benchmark.suppressErrors 引數略過這些錯誤。

此外,系統在評估模擬器或低電量裝置時也會回報錯誤,因為這樣可能會影響核心可用性和時鐘速度。

自訂基準測試

measureRepeated 函式可接受各種參數,這些參數會影響程式庫收集的指標、應用程式的啟動與編譯方式,或是基準測試將執行的疊代次數。

擷取指標

指標是從基準測試中擷取的主要資訊類型。可用選項包括 StartupTimingMetricFrameTimingMetricTraceSectionMetric。如要進一步瞭解相關資訊,請參閱擷取指標頁面。

使用自訂事件改善追蹤記錄資料

您可以透過自訂追蹤記錄事件,對應用程式進行檢測;透過其他追蹤記錄報表查看,有助您找出應用程式特有的問題。如要進一步瞭解如何建立自訂追蹤事件,請參閱定義自訂事件指南。

CompilationMode

Macrobenchmark 可指定 CompilationMode,這會定義多少應用程式程式碼應從 DEX 位元碼 (APK 中的位元碼格式) 預先編譯為機器碼 (類似預先編譯的 C++)。

根據預設,Macrobenchmark 是透過 CompilationMode.DEFAULT 執行,後者會在 Android 7 (API 層級 24) 以上版本中安裝基準設定檔 (如有)。如果您使用的是 Android 6 (API 級別 23) 以下的版本,編譯模式會將所有 APK 編譯為預設系統行為。

如果目標應用程式包含基準設定檔和 ProfileInstaller 程式庫,您就可以安裝基準設定檔。

在 Android 7 以上版本中,您可以自訂 CompilationMode 來影響裝置端預先編譯的資料量,會模擬不同時間的先進 (AOT) 編譯或 JIT 快取功能。請查看 CompilationMode.FullCompilationMode.PartialCompilationMode.None

這項功能以 ART 編譯指令為基礎。每次開始執行基準測試前,系統都會先清除設定檔資料,確保基準測試之間不會互相干擾。

啟動模式

如要執行活動開始,您可以傳遞預先定義的啟動模式 (COLDWARMHOT 其中之一)。這個參數會改變活動啟動時的方式,以及測試開始的流程狀態。

如要進一步瞭解啟動類型,請參閱 Android Vitals 啟動說明文件

範例

範例專案是 GitHub 上的 android/performance-samples 存放區的一部分。

提供意見

如要回報問題或提交 Jetpack Macrobenchmark 功能要求,請前往公開的 Issue Tracker