Mikro Karşılaştırma Yazma

Uygulama kodunuza değişiklikler ekleyerek Microbenchmark kitaplığını nasıl kullanacağınızı öğrenmek için Hızlı Başlangıç bölümüne bakın. Kod tabanınızda daha karmaşık değişiklikler yaparak tam kurulumu nasıl tamamlayacağınızı öğrenmek için Tam proje kurulumu bölümüne bakın.

Hızlı başlangıç kılavuzu

Bu bölümde, kodları modüllere taşımak zorunda kalmadan karşılaştırmayı nasıl deneyebileceğiniz ve tek seferlik ölçümleri nasıl çalıştırabileceğiniz gösterilmektedir. Doğru performans sonuçları için bu adımlar uygulamanızda hata ayıklamanın devre dışı bırakılmasını içerir. Bu nedenle, kaynak kontrol sisteminizde değişiklik yapmadan bunu yerel bir çalışma kopyasında saklayın.

Tek seferlik karşılaştırma yapmak için aşağıdakileri yapın:

  1. Kitaplığı, modülünüzün build.gradle veya build.gradle.kts dosyasına ekleyin:

    Kotlin

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

    Eski

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

    androidTestImplementation bağımlılığı yerine implementation bağımlılığı kullanın. androidTestImplementation kullanırsanız kitaplık manifest uygulama manifestiyle birleştirilmediği için karşılaştırmalar çalıştırılamaz.

  2. debug derleme türünü, hata ayıklaması mümkün olmayacak şekilde güncelleyin:

    Kotlin

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

    Eski

    android {
        ...
        buildTypes {
            debug {
                debuggable false
            }
        }
    }
    
  3. testInstrumentationRunner değerini AndroidBenchmarkRunner olacak şekilde değiştirin:

    Kotlin

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

    Eski

    android {
        ...
        defaultConfig {
            testInstrumentationRunner "androidx.benchmark.junit4.AndroidBenchmarkRunner"
        }
    }
    
  4. Karşılaştırmanızı dahil etmek için androidTest dizinindeki bir test dosyasına BenchmarkRule örneği ekleyin. Karşılaştırma yazma hakkında daha fazla bilgi için Mikrobenchmark sınıfı oluşturma bölümüne bakın.

    Aşağıdaki kod snippet'i, Araçlı bir teste nasıl karşılaştırma ekleneceğini gösterir:

    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()
                );
           }
        }
    }
    

Karşılaştırma yazma hakkında bilgi edinmek için Mikro Karşılaştırma sınıfı oluşturma bölümüne gidin.

Tam proje kurulumu

Tek seferlik karşılaştırma yerine düzenli karşılaştırmayı ayarlamak için karşılaştırmaları kendi modüllerinde ayırın. Bu, yapılandırmalarının (ör. debuggable değerini false olarak ayarlanması) normal testlerden ayrı olmasını sağlar.

Microbenchmark, kodunuzu doğrudan çalıştırdığından, karşılaştırmak istediğiniz kodu ayrı bir Gradle modülüne yerleştirin ve bu modüle bağımlılığı şekil 1'de gösterildiği gibi ayarlayın.

uygulama yapısı
Şekil 1. Microbenchmark'lar için :benchmarkable modülünde karşılaştırma kodu kullanmanızı sağlayan :app, :microbenchmark ve :benchmarkable Gradle modüllerini içeren uygulama yapısı.

Yeni bir Gradle modülü eklemek için Android Studio'daki modül sihirbazını kullanabilirsiniz. Sihirbaz, karşılaştırma için önceden yapılandırılmış bir modül oluşturur. Bu modül, bir karşılaştırma dizini ekler ve debuggable, false olarak ayarlanır.

  1. Android Studio'daki Proje panelinde projenizi veya modülünüzü sağ tıklayıp Yeni > Modül'ü tıklayın.

  2. Şablonlar bölmesinde Karşılaştırma'yı seçin.

  3. Karşılaştırma modülü türü olarak Mikrobenchmark'ı seçin.

  4. Modül adı olarak "microbenchmark" yazın.

  5. Son'u tıklayın.

Yeni kitaplık modülünü yapılandır
Şekil 2. Android Studio Bumblebee'ye yeni bir Gradle modülü ekleyin.

Modül oluşturulduktan sonra build.gradle veya build.gradle.kts dosyasını değiştirin ve androidTestImplementation öğesini, karşılaştırma yapacak kodu içeren modüle ekleyin:

Kotlin

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

Eski

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

Microbenchmark sınıfı oluşturma

Karşılaştırmalar, standart araç testleridir. Karşılaştırma oluşturmak için kitaplık tarafından sağlanan BenchmarkRule sınıfını kullanın. Etkinlikleri karşılaştırmak için ActivityScenario veya ActivityScenarioRule değerini kullanın. Karşılaştırma kullanıcı arayüzü kodunu kullanmak için @UiThreadTest kullanın.

Aşağıdaki kod örnek bir karşılaştırmayı gösterir:

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();
        }
    }
}
    

Kurulum için zamanlamayı devre dışı bırak

runWithTimingDisabled{} bloğuyla ölçmek istemediğiniz kod bölümleri için zamanlamayı devre dışı bırakabilirsiniz. Bu bölümler, genellikle karşılaştırmanın her yinelemesinde çalıştırmanız gereken birtakım kodları temsil eder.

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));
}
    

measureRepeated bloğunda ve runWithTimingDisabled içinde yapılan iş miktarını en aza indirmeye çalışın. measureRepeated bloku birden çok kez çalıştırılır ve karşılaştırmanın çalıştırılması için gereken toplam süreyi etkileyebilir. Bir karşılaştırmanın bazı sonuçlarını doğrulamanız gerekiyorsa bunu her yinelemede yapmak yerine son sonucu iddia edebilirsiniz.

Karşılaştırma yapın

Android Studio'da, Şekil 3'te gösterildiği gibi test sınıfınızın veya yönteminizin yanındaki oluk işlemini kullanarak karşılaştırmanızı herhangi bir @Test ile yaptığınız gibi çalıştırın.

Microbenchmark&#39;ı çalıştır
Şekil 3. Bir test sınıfının yanındaki oluk işlemini kullanarak Microbenchmark testi yapın.

Alternatif olarak, belirtilen Gradle modülündeki tüm testleri çalıştırmak için komut satırından connectedCheck komutunu çalıştırın:

./gradlew benchmark:connectedCheck

Veya tek bir test:

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

Karşılaştırma sonuçları

Başarılı bir Microbenchmark çalışmasından sonra, metrikler doğrudan Android Studio'da görüntülenir. Ayrıca, ek metrikler ve cihaz bilgilerini içeren tam bir karşılaştırma raporu da JSON biçiminde sunulur.

Mikrobenchmark sonuçları
Şekil 4. Microbenchmark sonuçları.

JSON raporları ve profil oluşturma izleri de cihazdan ana makineye otomatik olarak kopyalanır. Bunlar, ana makinede aşağıdaki konumda yazılır:

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

JSON raporu varsayılan olarak test APK'sının harici paylaşılan medya klasöründe, cihaz üzerindeki diske yazılır. Bu klasör genellikle /storage/emulated/0/Android/media/**app_id**/**app_id**-benchmarkData.json konumunda bulunur.

Yapılandırma hataları

Kitaplık, projenizin ve ortamınızın doğru yayın performansına ulaşacak şekilde ayarlandığından emin olmak için aşağıdaki koşulları algılar:

  • Hata ayıklanabilir false olarak ayarlandı.
  • Fiziksel bir cihaz kullanılıyor ve emülatörler desteklenmiyor.
  • Cihaz rootlanmışsa saatler kilitlenir.
  • Cihazda en az %25'lik yeterli pil seviyesi.

Önceki kontrollerden herhangi biri başarısız olursa karşılaştırma, yanlış ölçümleri önlemek için bir hata bildirir.

Belirli hata türlerini uyarı olarak bastırmak ve karşılaştırmayı durdurmasını önlemek için hata türünü virgülle ayrılmış bir liste halinde araç bağımsız değişkenine androidx.benchmark.suppressErrors iletin.

Bunu, aşağıdaki örnekte gösterildiği gibi Gradle komut dosyanızdan ayarlayabilirsiniz:

Kotlin

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

Eski

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

Ayrıca, komut satırından hataları da gizleyebilirsiniz:

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

Hataların engellenmesi, karşılaştırmanın yanlış yapılandırılmış bir durumda çalıştırılmasına olanak tanır ve karşılaştırma çıktısı, hata ile birlikte test adlarının başına eklenerek kasıtlı olarak yeniden adlandırılır. Örneğin, önceki snippet'teki atlamayla hata ayıklaması yapılabilir bir karşılaştırma çalıştırıldığında, test adlarının başına DEBUGGABLE_ eklenir.