剖析組建版本

較大型的專案或導入許多自訂建構邏輯的專案,您可能需要深入瞭解建構程序,以找出瓶頸。方法是剖析 Gradle 執行建構生命週期和每個建構工作各階段所需的時間長度。例如,如果版本設定檔顯示 Gradle 在設定專案時花費太多時間,建議您將自訂建構邏輯移出設定階段。此外,如果 mergeDevDebugResources 工作耗用了大量建構時間,可能表示您必須將圖片轉換為 WebP停用 PNG 壓縮功能。

如果您使用 Android Studio 4.0 或以上版本,建議您使用版本分析器調查建構效能問題。

此外,您可以透過下列兩種方式在 Android Studio 以外的位置剖析您的建構作業:

  1. 獨立的 gradle-profiler 工具,這項強大的工具可讓您深入分析建構作業。

  2. Gradle --profile 選項,這是 Gradle 指令列提供的便利工具。

使用獨立的 gradle-profiler 工具

如要尋找能提供最佳建構速度的專案設定,建議您使用 Gradle 分析器,這項工具可收集 Gradle 建構作業的剖析和基準化資訊。Gradle 分析器可讓您建立建構作業情境,並多次執行,可避免在結果之間出現高的差異,並確保結果可重現情況。

基準模式應用於收集簡潔和漸進式版本的相關資訊,而剖析模式可用來收集有關執行作業的詳情,包括 CPU 數據匯報。

一些用於基準化專案設置設定包括:

  • 外掛程式版本
  • Gradle 版本
  • JVM 設定 (堆積大小、permgen 大小、垃圾收集等)
  • Gradle 工作站數量 (org.gradle.workers.max)
  • 多種外掛程式選項,進一步最佳化效能

開始使用

  • 按照這些操作說明安裝 Gradle 分析器
  • 執行:gradle-profiler --benchmark --project-dir <root-project> :app:assembleDebug

這將對最新的建構進行基準化,因為 --benchmark 多次執行該工作,且不會在其間變更專案。這個指令會在 profile-out/ 目錄下產生 HTML 報告,顯示建構時間。

還有其他場景可能對基準化更實用:

  • 針對大部分作業的類別中,在「Method Body」中變更程式碼。
  • 可在專案中使用的模組中變更 API。相較於自訂程式碼的異動頻率較低,但這樣帶來的影響更大,也很適合用來評估。
  • 透過版面配置編輯器以模擬 UI 工作的疊代。
  • 字符串編輯以模擬處理翻譯工作。
  • 清理建構作業,以模擬建構作業本身的變化 (例如,Android Gradle 外掛程式更新、Gradle 更新,或是在 buildSrc 下編輯自己的建構程式碼)。

如要針對這些用途進行基準化,您可以建立情境以用於驅動 gradle-profiler 執行,並對來源資料進行適當變更。以下列舉一些常見的使用情境。

剖析不同的記憶體/CPU 設定

如要針對不同的記憶體和 CPU 設定進行基準化,您可以建立多種情境,讓 org.gradle.jvmargs 使用不同的值。例如,您可以建立情境:

# <root-project>/scenarios.txt
clean_build_2gb_4workers {
    tasks = [":app:assembleDebug"]
    gradle-args = ["--max-workers=4"]
    jvm-args = ["-Xmx2048m"]
    cleanup-tasks = ["clean"]
}
clean_build_parallelGC {
    tasks = [":app:assembleDebug"]
    jvm-args = ["-XX:+UseParallelGC"]
    cleanup-tasks = ["clean"]
}

clean_build_G1GC_4gb {
    tasks = [":app:assembleDebug"]
    jvm-args = ["-Xmx4096m", "-XX:+UseG1GC"]
    cleanup-tasks = ["clean"]
}

執行 gradle-profiler --benchmark --project-dir <root-project> --scenario-file scenarios.txt 會執行三個情境,而您可以比較 :app:assembleDebug 的每項設定所需時間。

剖析不同的 Gradle 外掛程式版本

如要瞭解變更 Gradle 外掛程式的版本對建構時間有何影響,請建立一個場景,以對其進行基準化。這需要一些準備工作,才能讓外掛程式版本可從場景植入。變更根目錄的 build.gradle:

# <root-project>/build.gradle
buildscript {
    def agpVersion = providers.systemProperty("agpVersion").forUseAtConfigurationTime().orNull ?: '4.1.0'

    ext.kotlin = providers.systemProperty('kotlinVersion').forUseAtConfigurationTime().orNull ?: '1.4.0'

    dependencies {
        classpath "com.android.tools.build:gradle:$agpVersion"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin"
    }
}

現在,您可以從情境檔案指定 Android Gradle 外掛程式和 Kotlin Gradle 外掛程式,並嘗試在來源檔案中新增方法:

# <root-project>/scenarios.txt
non_abi_change_agp4.1.0_kotlin1.4.10 {
    tasks = [":app:assembleDebug"]
    apply-abi-change-to ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
    System-properties {
      "agpVersion" = "4.1.0"
      "kotlinVersion" = "1.4.10"
}

non_abi_change_agp4.2.0_kotlin1.4.20 {
    tasks = [":app:assembleDebug"]
    apply-abi-change-to ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
    System-properties {
      "agpVersion" = "4.2.0-alpha16"
      "kotlinVersion" = "1.4.20"
}

剖析漸進式建構作業

大部分的建構作業都會逐步增加,而這是建構前最重要場景之一。Gradle 分析器有剖析漸進式建構作業的拓展支援。這項服務可以變更方法內容、新增方法或變更版面配置或字串資源,藉此自動將變更套用至來源檔案。例如,您可以建立像這樣的漸進式場景:

# <root-project>/scenarios.txt
non_abi_change {
    tasks = [":app:assembleDebug"]
    apply-non-abi-change-to = ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
}

abi_change {
    tasks = [":app:assembleDebug"]
    apply-abi-change-to = ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
}

layout_change {
    tasks = [":app:assembleDebug"]
    apply-android-layout-change-to = "app/src/main/res/your_layout_file.xml"
}
string_resource_change {
    tasks = [":app:assembleDebug"]
    apply-android-resource-value-change-to = "app/src/main/res/values/strings.xml"
}

執行 gradle-profiler --benchmark --project-dir &lt;root-project> --scenario-file scenarios.txt 時,系統會產生包含基準化資料的 HTML 報表。

您可以將漸進式場景與其他設定結合,例如堆積大小、工作站數量或 Gradle 版本:

# <root-project>/scenarios.txt
non_abi_change_4g {
    tasks = [":app:assembleDebug"]
    apply-non-abi-change-to ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
    jvm-args = ["-Xmx4096m"]
}

non_abi_change_4g_8workers {
    tasks = [":app:assembleDebug"]
    apply-non-abi-change-to ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
    jvm-args = ["-Xmx4096m"]
    gradle-args = ["--max-workers=8"]
}

non_abi_change_3g_gradle67 {
    tasks = [":app:assembleDebug"]
    apply-non-abi-change-to ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
    jvm-args = ["-Xmx3072m"]
    version = ["6.7"]
}

剖析簡潔式建構作業

如要為簡潔版本建構基準,您可以建立情境,創建用於驅動 Gradle 分析器執行的場景:

# <root-project>/scenarios.txt
clean_build {
    tasks = [":app:assembleDebug"]
    cleanup-tasks = ["clean"]
}

如要執行這個情境,請使用下列指令:

gradle-profiler --benchmark --project-dir <root-project> --scenario-file scenarios.txt

使用 Gradle --profile 選項

如要透過 Gradle 指令列產生和查看建構設定檔,請執行下列步驟:

  1. 開啟專案根目錄中的指令列終端機。
  2. 輸入下列指令,執行簡潔式建構作業。在計算建構時,您應該在設定檔的每個建構作業之間執行簡潔式建構作業,因為當工作的輸入 (例如原始碼) 沒有改變時,Gradle 會略過工作。因此,由於沒有重新執行工作,沒有輸入變更的第二次建構會執行得更快。因此,在建構之間執行 clean 工作,可確保剖析完整的建構程序。
    // On Mac or Linux, run the Gradle wrapper using "./gradlew".
    gradlew clean
    
  3. 使用下列旗標,執行任一變種版本的偵錯版本 (例如「dev」(開發) 版本):
    gradlew --profile --offline --rerun-tasks assembleFlavorDebug
    
    • --profile:啟用剖析功能。
    • --offline:禁止 Gradle 擷取線上依附元件。這可確保 Gradle 嘗試更新依附元件所造成的延遲情況不會干擾您的剖析資料。您應已建構過一次專案,以確保 Gradle 已下載並快取依附元件。
    • --rerun-tasks:強制 Gradle 重新執行所有工作並忽略任何工作最佳化。
  4. 圖 1.專案檢視畫面指示設定檔報告的位置。

    建構完成後,請使用「Project」(專案) 視窗前往 project-root/build/reports/profile/ 目錄 (如圖 1 所示)。

  5. profile-timestamp.html 檔案上點擊滑鼠右鍵,然後選取「Open in Browser」(在瀏覽器中開啟) > 「Default」(預設)。報表類似圖 2 所示。您可以查看報表中的每個分頁來瞭解您的建構作業,例如「Task Execution」(工作執行) 分頁會顯示 Gradle 執行每個建構工作所需的時間。

    圖 2.在瀏覽器中查看報表。

  6. 選用:變更專案或建構設定之前,請先重複步驟 3 中的指令,但省略 --rerun-tasks 旗標。因為 Gradle 會嘗試在未變更資料的情況下重新執行資料,以節省寶貴時間 (在報表的「Task Execution」(工作執行) 分頁中會顯示為 UP-TO-DATE),如圖 3 所示),您可以找出哪些工作正在執行不應執行的工作。例如,如果 :app:processDevUniversalDebugManifest 未標示為 UP-TO-DATE,則建議使用建構設定以動態方式更新資訊清單的每個版本。不過,部分工作必須在每個建構作業中執行,例如 :app:checkDevDebugManifest

    圖 3.檢視工作執行結果。

您已經取得了建構設定檔報表,可以開始檢查報表各分頁的資訊,找出最佳化商機。部分建構設定需要實驗,因為專案和工作站的福利可能各有不同。例如,程式碼集數量龐大的專案或許就能利用程式碼縮減機制,移除未使用的程式碼並縮減應用程式大小。但較小的專案可能會因為停用程式碼縮減而受益。此外,增加 Gradle 堆積大小 (使用 org.gradle.jvmargs) 可能會對低記憶體機器的效能造成負面影響。

變更建構設定後,請重複上述步驟並建立新的建構設定檔,以觀察變更的結果。例如,圖 4 顯示的是應用本頁中描述的一些基本最佳化後,同一個範例應用程式的報表。

圖 4.在最佳化建構速度後查看新報表。