Profil für Build erstellen

Größere Projekte oder Projekte, die viel benutzerdefinierte Build-Logik implementieren, müssen Sie den Build-Prozess genauer untersuchen, um Engpässe zu finden. Dazu erstellen Sie ein Profil, wie lange Gradle benötigt, um die einzelnen Phasen des Build-Lebenszyklus und jeder Build-Aufgabe. Wenn Ihr Build-Profil beispielsweise dass Gradle zu viel Zeit für die Konfiguration Ihres Projekts aufwendet, schlagen vor, dass Sie verschieben Sie die benutzerdefinierte Build-Logik aus der Konfigurationsphase. Wenn die Aufgabe mergeDevDebugResources viel Zeit in Anspruch nimmt der Build-Zeit kann dies darauf hindeuten, dass Sie entweder konvertiere deine Bilder in WebP oder deaktivieren Sie die PNG-Verarbeitung.

Wenn Sie Android Studio 4.0 oder höher: die beste Möglichkeit, die Build-Leistung zu untersuchen können Sie Build Analyzer verwenden.

Darüber hinaus gibt es zwei Optionen für die Erstellung eines Build-Profils außerhalb von Android Studio:

  1. Das eigenständige gradle-profiler-Tool, ein ist ein zuverlässiges Tool, mit dem Sie Ihren Build umfassend analysieren können.

  2. Mit der Gradle-Option --profile ist ein praktisches Tool in der Gradle-Befehlszeile.

Eigenständiges gradle-profiler-Tool verwenden

Um die Projektkonfiguration zu finden, die Ihnen die beste Build-Geschwindigkeit ermöglicht, sollten Sie Gradle profiler verwenden. Ein Tool zum Erfassen von Profiling- und Benchmarking-Informationen für Gradle-Builds. Mit Gradle-Profiler können Sie Build-Szenarien erstellen und mehrere Dadurch werden große Abweichungen zwischen den Ergebnissen vermieden und die Reproduzierbarkeit der Ergebnisse.

Benchmarking-Modus sollte verwendet werden, um Informationen über saubere und inkrementelle Builds zu sammeln, während der Profilerstellungsmodus können verwendet werden, um detailliertere Informationen zu den Ausführungen zu erfassen, einschließlich Snapshots.

Für das Benchmarking sind u. a. folgende Konfigurationen möglich:

  • Plug-in-Versionen
  • Gradle-Versionen
  • JVM-Einstellungen (Heap-Größe, Permgengröße, automatische Speicherbereinigung usw.)
  • Anzahl der Gradle-Worker (org.gradle.workers.max)
  • Optionen pro Plug-in zur weiteren Leistungsoptimierung

Erste Schritte

  • Installieren Sie Gradle-profiler gemäß dieser Anleitung.
  • Ausführen: gradle-profiler --benchmark --project-dir <root-project> :app:assembleDebug

Dies bezieht sich auf einen vollständig aktuellen Build, da --benchmark den ohne das Projekt dazwischen zu ändern. Dann wird es Erstelle einen HTML-Bericht im Verzeichnis profile-out/ mit den Erstellungszeiten.

Es gibt weitere Szenarien, die für das Benchmarking möglicherweise hilfreicher sind:

  • Codeänderungen im Methodentext einer Klasse, in der Sie die meiste Arbeit erledigen.
  • API-Änderungen in einem Modul, das im gesamten Projekt verwendet wird. Obwohl weniger häufiger als Änderungen am eigenen Code, hat das größere Auswirkungen um sie zu messen.
  • Layoutbearbeitungen zur Simulation von UI-Arbeiten
  • Stringbearbeitungen, um den Umgang mit der Übersetzung zu simulieren.
  • Bereinigen Sie Builds, um Änderungen am Build selbst zu simulieren (z.B. Android-Gradle Plug-in-Update, Gradle-Update oder Änderungen an Ihrem eigenen Build-Code unter buildSrc).

Um diese Anwendungsfälle zu vergleichen, können Sie ein Szenario erstellen, wird zur Ausführung von gradle-profiler verwendet und gilt entsprechend Änderungen an Ihren Quellen. Im Folgenden finden Sie einige häufige Szenarien.

Profilerstellung für verschiedene Arbeitsspeicher-/CPU-Einstellungen

Um verschiedene Arbeitsspeicher- und CPU-Einstellungen zu vergleichen, Mehrere Szenarien, bei denen unterschiedliche Werte für org.gradle.jvmargs verwendet werden Für können Sie Szenarien erstellen:

# <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"]
}

Wird ausgeführt: gradle-profiler --benchmark --project-dir <root-project> --scenario-file scenarios.txt drei Szenarien ausgeführt und Sie können vergleichen, :app:assembleDebug für jede dieser Konfigurationen.

Profilerstellung für verschiedene Gradle-Plug-in-Versionen

Um herauszufinden, wie sich eine Änderung der Version des Gradle-Plug-ins auf erstellen Sie ein Szenario zum Benchmarking dieser Daten. Dies erfordert einige die Plug-in-Version aus dem Szenario injizierbar zu machen. Ändern Ihren Stamm 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"
    }
}

Sie können jetzt das Android-Gradle-Plug-in und das Kotlin-Gradle-Plug-in angeben aus der Datei mit den Szenarien erstellen und dem Szenario eine neue Methode hinzufügen die Quelldateien:

# <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"
}

Profil für inkrementellen Build erstellen

Da die meisten Builds inkrementell erstellt werden, Szenarien zu erstellen. Gradle-Profiler bietet umfassende Unterstützung für Profilerstellung für inkrementelle Builds Änderungen können automatisch auf eine Quelldatei angewendet werden, indem , das Hinzufügen einer neuen Methode oder das Ändern einer Layout- oder String-Ressource. Für können Sie inkrementelle Szenarien wie folgt erstellen:

# <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"
}

Wird ausgeführt: gradle-profiler --benchmark --project-dir &lt;root-project> --scenario-file scenarios.txt den HTML-Bericht mit den Benchmarking-Daten.

Sie können inkrementelle Szenarien mit anderen Einstellungen wie Heap-Größe, Anzahl der Worker oder der Gradle-Version:

# <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"]
}

Profil für sauberen Build erstellen

Um einen sauberen Build zu bewerten, können Sie ein Szenario erstellen, zum Steuern der Ausführung von gradle-profiler:

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

Verwenden Sie den folgenden Befehl, um dieses Szenario auszuführen:

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

Gradle-Option --profile verwenden

Führen Sie den folgenden Befehl aus, um ein Build-Profil über die Gradle-Befehlszeile zu generieren und aufzurufen: führen Sie die folgenden Schritte aus:

  1. Öffnen Sie ein Befehlszeilenterminal im Stammverzeichnis Ihres Projekts.
  2. Führen Sie mit dem folgenden Befehl einen sauberen Build aus. Während des Profils sollten Sie zwischen den einzelnen Build-Profilen einen sauberen Build ausführen. da Gradle Aufgaben überspringt, wenn Eingaben in eine Aufgabe (z. B. Quellcode) dies nicht tun ändern können. Daher wird ein zweiter Build ohne Eingabeänderungen immer schneller ausgeführt, Aufgaben nicht erneut ausgeführt werden. Die Ausführung der clean-Aufgabe zwischen Ihre Builds stellen sicher, dass Sie ein Profil für den gesamten Build-Prozess erstellen.
    // On Mac or Linux, run the Gradle wrapper using "./gradlew".
    gradlew clean
    
  3. Führe einen Debug-Build für eine deiner Produkt-Varianten aus, z. B. „dev“ Geschmack, mit den folgenden Flags:
    gradlew --profile --offline --rerun-tasks assembleFlavorDebug
    
    • --profile: Aktiviert die Profilerstellung.
    • --offline: Deaktiviert Gradle das Abrufen von Online-Daten. Abhängigkeiten. So sorgen Sie dafür, dass keine durch Gradle verursachten Verzögerungen wenn Sie versuchen, Ihre Abhängigkeiten zu aktualisieren, Datenprofil erstellen. Sie sollten Ihr Projekt bereits erstellt haben, Prüfen Sie, ob Gradle Ihre Abhängigkeiten bereits heruntergeladen und im Cache gespeichert hat.
    • --rerun-tasks: zwingt Gradle, alle Aufgaben noch einmal auszuführen und zu ignorieren Aufgabenoptimierungen.
  4. Abbildung 1: Projektansicht, die den Standort Profilberichten.

    Nachdem der Build abgeschlossen ist, navigieren Sie im Fenster Project (Projekt) zum Verzeichnis project-root/build/reports/profile/ (als wie in Abbildung 1 dargestellt).

  5. Klicken Sie mit der rechten Maustaste auf die Datei profile-timestamp.html und wählen Sie Im Browser öffnen > Standard: Der Bericht sollte in etwa so aussehen: wie in Abbildung 2 dargestellt. Auf jedem Tab im Bericht finden Sie Informationen dazu, wie zum Beispiel auf dem Tab Task Execution (Aufgabenausführung) zum Ausführen der einzelnen Build-Aufgaben.

    Abbildung 2: Aufrufen eines Berichts in einem Browser

  6. Optional:Bevor Sie Änderungen an Ihrem Projekt oder Build vornehmen den Befehl aus Schritt 3 wiederholen, aber den --rerun-tasks-Flag. Da Gradle versucht, Zeit zu sparen, noch einmal auszuführende Aufgaben ausführen, deren Eingaben sich nicht geändert haben (diese werden als UP-TO-DATE auf dem Tab Task Execution (Aufgabenausführung) des Berichts, wie gezeigt in Abbildung 3), können Sie feststellen, welche Aufgaben Arbeit ausführen, nicht sein sollte. Wenn zum Beispiel der Parameter :app:processDevUniversalDebugManifest ist nicht markiert als UP-TO-DATE, schlägt dies möglicherweise vor, dass die Build-Konfiguration so ist, das Manifest bei jedem Build dynamisch aktualisieren. Einige Aufgaben müssen jedoch während jedes Builds ausgeführt werden, z. B. :app:checkDevDebugManifest.

    Abbildung 3: Ergebnisse der Aufgabenausführung ansehen.

Da Sie nun über einen Build-Profilbericht verfügen, können Sie nun nach Optimierungsmöglichkeiten, indem Sie die Informationen auf den einzelnen Tabs der Seite Bericht. Einige Build-Einstellungen erfordern Tests, da die Vorteile möglicherweise und Workstations unterscheiden. Zum Beispiel Projekte mit einer großen Codebasis kann von Codeverkleinerung profitieren um nicht verwendeten Code zu entfernen und die App-Größe zu verringern. Kleinere Projekte könnten mehr davon profitieren, den Code vollständig zu deaktivieren. Außerdem die Größe des Gradle-Heaps mit <ph type="x-smartling-placeholder"></ph> org.gradle.jvmargs) kann sich negativ auf die Leistung auf Maschinen mit wenig Arbeitsspeicher auswirken.

Nachdem Sie die Build-Konfiguration geändert haben, beobachten Sie die Ergebnisse der Ihre Änderungen vornehmen, indem Sie die oben genannten Schritte wiederholen und ein neues Build-Profil erstellen. Abbildung 4 zeigt beispielsweise einen Bericht für dieselbe Beispiel-App nach dem Anwenden einige der auf dieser Seite beschriebenen grundlegenden Optimierungen.

Abbildung 4: Aufrufen eines neuen Berichts nach der Optimierung des Builds Geschwindigkeit.