Mikro-Benchmark schreiben

Um zu erfahren, wie Sie die MicroBenchmark-Bibliothek verwenden können, indem Sie Änderungen an Ihrem finden Sie im Abschnitt Kurzanleitung. Wenn Sie mehr darüber erfahren möchten, wie Sie eine vollständige Einrichtung mit komplizierteren Änderungen an Ihrer Codebasis durchführen, siehe Abschnitt Vollständige Projekteinrichtung.

Kurzanleitung

In diesem Abschnitt erfahren Sie, wie Sie Benchmarking ausprobieren und einmalige Messungen durchführen. ohne Code in Module verschieben zu müssen. Um genaue Leistungsergebnisse zu erhalten, Dazu muss die Fehlerbehebung in Ihrer App deaktiviert werden. ohne die Änderungen in Ihr Versionsverwaltungssystem zu übernehmen.

So führen Sie ein einmaliges Benchmarking durch:

  1. Fügen Sie die Bibliothek der Datei build.gradle oder build.gradle.kts Ihres Moduls hinzu:

    Kotlin

    dependencies {
        implementation("androidx.benchmark:benchmark-junit4:1.2.3")
    }
    

    Cool

    dependencies {
        implementation 'androidx.benchmark:benchmark-junit4:1.2.3'
    }
    

    Eine implementation-Abhängigkeit anstelle einer androidTestImplementation verwenden Abhängigkeit. Wenn Sie androidTestImplementation verwenden, entsprechen die Benchmarks ausgeführt, da das Bibliotheksmanifest nicht mit der App zusammengeführt wurde Manifests.

  2. Aktualisieren Sie den Build-Typ debug, damit er nicht debuggen kann:

    Kotlin

    android {
        ...
        buildTypes {
            debug {
                isDebuggable = false
            }
        }
    }
    

    Cool

    android {
        ...
        buildTypes {
            debug {
                debuggable false
            }
        }
    }
    
  3. Ändern Sie testInstrumentationRunner in AndroidBenchmarkRunner:

    Kotlin

    android {
        ...
        defaultConfig {
            testInstrumentationRunner = "androidx.benchmark.junit4.AndroidBenchmarkRunner"
        }
    }
    

    Cool

    android {
        ...
        defaultConfig {
            testInstrumentationRunner "androidx.benchmark.junit4.AndroidBenchmarkRunner"
        }
    }
    
  4. Fügen Sie eine Instanz von BenchmarkRule in einer Testdatei im androidTest, um die Benchmark hinzuzufügen. Weitere Informationen Informationen zum Schreiben von Benchmarks finden Sie unter MicroBenchmark-Klasse erstellen.

    Im folgenden Code-Snippet sehen Sie, wie Sie einer instrumentierten Test:

    Kotlin

    @RunWith(AndroidJUnit4::class)
    class SampleBenchmark {
        @get:Rule
        val benchmarkRule = BenchmarkRule()
    
        @Test
        fun benchmarkSomeWork() {
            benchmarkRule.measureRepeated {
                doSomeWork()
            }
        }
    }
    

    Java

    @RunWith(AndroidJUnit4.class)
    class SampleBenchmark {
        @Rule
        public BenchmarkRule benchmarkRule = new BenchmarkRule();
    
        @Test
        public void benchmarkSomeWork() {
                BenchmarkRuleKt.measureRepeated(
                    (Function1<BenchmarkRule.Scope, Unit>) scope -> doSomeWork()
                );
           }
        }
    }
    

Informationen zum Schreiben einer Benchmark finden Sie unter MicroBenchmark-Klasse erstellen.

Vollständige Projekteinrichtung

Um ein regelmäßiges Benchmarking anstelle einmaliger Benchmarking einzurichten, isolieren Sie die Benchmarks in einem eigenen Modul an. So wird sichergestellt, dass ihre Konfiguration, wie z. B. das Festlegen von debuggable auf false, unterscheidet sich von regulären Tests.

Da MicroBenchmark Ihren Code direkt ausführt, platzieren Sie den Code, den Sie Benchmark in einem separaten Gradle-Modul und setze die Abhängigkeit von diesem Modul als wie in Abbildung 1 dargestellt.

<ph type="x-smartling-placeholder">
</ph> App-Struktur
Abbildung 1: Anwendungsstruktur mit :app, Gradle :microbenchmark und :benchmarkable Module, mit denen MicroBenchmarks Code im Modul :benchmarkable.

Mit dem Modulassistenten in Android Studio können Sie ein neues Gradle-Modul hinzufügen. Die ein für das Benchmarking vorkonfiguriertes Modul mit einem Benchmarkverzeichnis hinzugefügt und debuggable auf false festgelegt.

  1. Klicken Sie in Android im Bereich Project (Projekt) mit der rechten Maustaste auf Ihr Projekt oder Modul. Studio an und klicken Sie auf Neu > Modul.

  2. Wählen Sie im Bereich Templates (Vorlagen) die Option Benchmark aus.

  3. Wählen Sie als Typ des Benchmark-Moduls MicroBenchmark aus.

  4. Geben Sie „MicroBenchmark“ ein. als Modulnamen.

  5. Klicken Sie auf Fertig.

<ph type="x-smartling-placeholder">
</ph> Neues Bibliotheksmodul konfigurieren
Abbildung 2. Neues Gradle-Modul in Android Studio hinzufügen Hummel.

Nachdem das Modul erstellt wurde, ändern Sie build.gradle oder build.gradle.kts und fügen Sie androidTestImplementation in das Modul ein, das den Code enthält, Benchmark:

Kotlin

dependencies {
    // The module name might be different.
    androidTestImplementation(project(":benchmarkable"))
}

Cool

dependencies {
    // The module name might be different.
    androidTestImplementation project(':benchmarkable')
}

MicroBenchmark-Klasse erstellen

Benchmarks sind Standard-Instrumentierungstests. Verwenden Sie zum Erstellen einer Benchmark die Methode BenchmarkRule-Klasse, die von der Bibliothek bereitgestellt wird. Um Aktivitäten zu vergleichen, verwenden Sie ActivityScenario oder ActivityScenarioRule Um den UI-Code zu vergleichen, Verwenden Sie @UiThreadTest.

Der folgende Code zeigt ein Beispiel für eine Benchmark:

Kotlin

@RunWith(AndroidJUnit4::class)
class SampleBenchmark {
    @get:Rule
    val benchmarkRule = BenchmarkRule()

    @Test
    fun benchmarkSomeWork() {
        benchmarkRule.measureRepeated {
            doSomeWork()
        }
    }
}
    

Java

@RunWith(AndroidJUnit4.class)
class SampleBenchmark {
    @Rule
    public BenchmarkRule benchmarkRule = new BenchmarkRule();

    @Test
    public void benchmarkSomeWork() {
        final BenchmarkState state = benchmarkRule.getState();
        while (state.keepRunning()) {
            doSomeWork();
        }
    }
}
    

Zeit für die Einrichtung deaktivieren

Sie können das Timing für Codeabschnitte deaktivieren, die Sie nicht mit dem runWithTimingDisabled{}-Block. Diese Abschnitte stehen in der Regel Code, den Sie bei jeder Iteration der Benchmark ausführen müssen.

Kotlin

// using random with the same seed, so that it generates the same data every run
private val random = Random(0)

// create the array once and just copy it in benchmarks
private val unsorted = IntArray(10_000) { random.nextInt() }

@Test
fun benchmark_quickSort() {
    // ...
    benchmarkRule.measureRepeated {
        // copy the array with timing disabled to measure only the algorithm itself
        listToSort = runWithTimingDisabled { unsorted.copyOf() }

        // sort the array in place and measure how long it takes
        SortingAlgorithms.quickSort(listToSort)
    }

    // assert only once not to add overhead to the benchmarks
    assertTrue(listToSort.isSorted)
}
    

Java

private final int[] unsorted = new int[10000];

public SampleBenchmark() {
    // Use random with the same seed, so that it generates the same data every
    // run.
    Random random = new Random(0);

    // Create the array once and copy it in benchmarks.
    Arrays.setAll(unsorted, (index) -> random.nextInt());
}

@Test
public void benchmark_quickSort() {
    final BenchmarkState state = benchmarkRule.getState();

    int[] listToSort = new int[0];

    while (state.keepRunning()) {
        
        // Copy the array with timing disabled to measure only the algorithm
        // itself.
        state.pauseTiming();
        listToSort = Arrays.copyOf(unsorted, 10000);
        state.resumeTiming();
        
        // Sort the array in place and measure how long it takes.
        SortingAlgorithms.quickSort(listToSort);
    }

    // Assert only once, not to add overhead to the benchmarks.
    assertTrue(SortingAlgorithmsKt.isSorted(listToSort));
}
    

Versuchen Sie, den Arbeitsaufwand innerhalb des measureRepeated-Blocks zu minimieren. und innerhalb von runWithTimingDisabled. Der Block measureRepeated wird mehrfach ausgeführt und kann sich auf die Gesamtzeit auswirken, die zum Ausführen der Benchmark benötigt wird. Wenn Sie Ergebnisse einer Benchmark überprüfen müssen, können Sie anstatt bei jeder Iteration der Benchmark.

Benchmark ausführen

Führen Sie in Android Studio Ihre Benchmark wie bei jeder @Test mit der neben der Testklasse oder -methode, wie in Abbildung 3 dargestellt.

<ph type="x-smartling-placeholder">
</ph> MicroBenchmark ausführen
Abbildung 3: MicroBenchmark-Test mit der Gutteraktion durchführen neben einem Testkurs.

Alternativ können Sie über die Befehlszeile connectedCheck ausführen, um alle der Tests aus dem angegebenen Gradle-Modul:

./gradlew benchmark:connectedCheck

Oder einen einzelnen Test:

./gradlew benchmark:connectedCheck -P android.testInstrumentationRunnerArguments.class=com.example.benchmark.SampleBenchmark#benchmarkSomeWork

Benchmarkergebnisse

Nach erfolgreicher MicroBenchmark-Ausführung werden Messwerte direkt in Android angezeigt. Studio und ein vollständiger Benchmarkbericht mit zusätzlichen Messwerten und Geräten sind im JSON-Format verfügbar.

<ph type="x-smartling-placeholder">
</ph> MicroBenchmark-Ergebnisse
Abbildung 4: MicroBenchmark-Ergebnisse.

JSON-Berichte und alle Profilerstellungs-Traces werden ebenfalls automatisch vom Gerät kopiert. die Sie hosten möchten. Sie werden an folgendem Speicherort auf dem Hostcomputer geschrieben:

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

Standardmäßig wird der JSON-Bericht im extern freigegebener Medienordner, der sich in der Regel in /storage/emulated/0/Android/media/**app_id**/**app_id**-benchmarkData.json

Konfigurationsfehler

Die Bibliothek erkennt die folgenden Bedingungen, damit Ihr Projekt und -Umgebung für Release-genaue Leistung eingerichtet sind:

  • „Debuggable“ ist auf false festgelegt.
  • Ein physisches Gerät wird verwendet – Emulatoren werden nicht unterstützt.
  • Die Uhr wird gesperrt, wenn das Gerät gerootet ist.
  • Der Akkuladestand des Geräts ist bei mindestens 25 % ausreichend.

Wenn eine der vorherigen Prüfungen fehlschlägt, meldet die Benchmark einen Fehler an ungenaue Messungen vermeiden.

Um bestimmte Fehlertypen als Warnungen zu unterdrücken und zu verhindern, dass sie die Benchmark, übergeben Sie den Fehlertyp in einer durch Kommas getrennten Liste an die Instrumentierung Argument androidx.benchmark.suppressErrors

Sie können dies über Ihr Gradle-Skript festlegen, wie im folgenden Beispiel gezeigt:

Kotlin

android {
    defaultConfig {
       …
      testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "DEBUGGABLE,LOW-BATTERY"
    }
}

Cool

android {
    defaultConfig {
       …
      testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "DEBUGGABLE,LOW-BATTERY"
    }
}

Sie können Fehler auch über die Befehlszeile unterdrücken:

$ ./gradlew :benchmark:connectedCheck -P andoidtestInstrumentationRunnerArguments.androidx.benchmark.supperssErrors=DEBUGGABLE,LOW-BATTERY

Wenn Sie Fehler unterdrücken, wird die Benchmark in einem falsch konfigurierten Zustand ausgeführt. und die Benchmark-Ausgabe bewusst umbenannt wird, indem der Test Namen mit dem Fehler. Wenn Sie z. B. eine debugfähige Benchmark mit dem Durch die Unterdrückung im vorherigen Snippet wird Testnamen das Zeichen DEBUGGABLE_ vorangestellt.