Mikro Karşılaştırma Yazma

Uygulama kodunuza değişiklik 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 içeren tam bir kurulumu nasıl tamamlayacağınızı öğrenmek için Tam proje kurulumu bölümüne bakın.

Hızlı Başlangıç

Bu bölümde, kodu modüllere taşımak zorunda kalmadan karşılaştırmalı test yapmanın ve tek seferlik ölçümler yapmanın nasıl yapılacağı gösterilmektedir. Doğru performans sonuçları için bu adımlarda uygulamanızda hata ayıklamanın devre dışı bırakılması gerekir. Bu nedenle, değişiklikleri kaynak denetim sisteminize kaydetmeden bu dosyayı yerel bir çalışma kopyasında tutun.

Tek seferlik bir 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.4")
    }

    Groovy

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

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

  2. debug derleme türünü hata ayıklama yapılamayacak şekilde güncelleyin:

    Kotlin

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

    Groovy

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

    Kotlin

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

    Groovy

    android {
        ...
        defaultConfig {
            testInstrumentationRunner "androidx.benchmark.junit4.AndroidBenchmarkRunner"
        }
    }
  4. Karşılaştırmanızı eklemek için androidTest dizininde bir test dosyasına BenchmarkRule örneği ekleyin. Karşılaştırma yazma hakkında daha fazla bilgi için Mikro Karşılaştırma sınıfı oluşturma başlıklı makaleyi inceleyin.

    Aşağıdaki kod snippet'inde, bir Ölçülmüş teste nasıl karşılaştırma ölçütü ekleneceği gösterilmektedir:

    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ırmayı nasıl yazacağınızı öğrenmek için Mikro karşılaştırma sınıfı oluşturma bölümüne atlayın.

Tam proje kurulumu

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

Microbenchmark, kodunuzu doğrudan çalıştırdığından, karşılaştırma yapmak 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. :app, :microbenchmark ve :benchmarkable Gradle modüllerine sahip uygulama yapısı. Bu yapı, mikro karşılaştırma testlerinin :benchmarkable modülündeki kodu karşılaştırmasına olanak tanır.

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

  1. Android Studio'daki Proje panelinde projenizi veya modülünüzü sağ tıklayın ve 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 Mikro Karşılaştırma'yı seçin.

  4. Modül adı için "microbenchmark" yazın.

  5. Son'u tıklayın.

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

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

Kotlin

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

Groovy

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

Mikro karşılaştırma sınıfı oluşturma

Karşılaştırma ölçütleri, standart enstrümantasyon 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 simgesini kullanın. Kullanıcı arayüzü kodunu karşılaştırmak için @UiThreadTest kodunu kullanın.

Aşağıdaki kodda örnek bir karşılaştırma gösterilmektedir:

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ırakma

Ölçmek istemediğiniz kod bölümlerinin zamanlamasını runWithTimingDisabled{} bloğuyla devre dışı bırakabilirsiniz. Bu bölümler genellikle karşılaştırmanın her iterasyonunda çalıştırmanız gereken bazı 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 çalışma miktarını en aza indirmeye çalışın. measureRepeated bloğu birden çok kez çalıştırılır ve karşılaştırmayı çalıştırmak için gereken toplam süreyi etkileyebilir. Bir karşılaştırmanın bazı sonuçlarını doğrulamanız gerekiyorsa karşılaştırmanın her iterasyonunda doğrulama yapmak yerine son sonucu doğrulayabilirsiniz.

Karşılaştırmayı çalıştırma

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

Mikro Karşılaştırma Çalıştırma
Şekil 3. Test sınıfının yanındaki kenar boşluğu işlemini kullanarak mikro karşılaştırma testini çalıştırı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ı

Mikro karşılaştırma başarılı bir şekilde çalıştırıldıktan sonra metrikler doğrudan Android Studio'da görüntülenir ve ek metrikler ile cihaz bilgilerini içeren tam bir karşılaştırma raporu JSON biçiminde kullanılabilir.

Mikro karşılaştırma sonuçları
Şekil 4. Mikro karşılaştırma sonuçları.

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

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

JSON raporu varsayılan olarak cihazdaki test APK'sının harici paylaşılan medya klasörüne yazılır. Bu klasör genellikle /storage/emulated/0/Android/media/**app_id**/**app_id**-benchmarkData.json konumundadır.

Yapılandırma hataları

Kitaplık, projenizin ve ortamın yayına uygun performans için ayarlandığından emin olmak amacıyla aşağıdaki koşulları algılar:

  • Hata ayıklama yapılabilir özelliği false olarak ayarlanmıştır.
  • Fiziksel bir cihaz kullanılıyorsa (emülatörler desteklenmez).
  • Cihaz rootlanmışsa saatler kilitlenir.
  • Cihazın pil seviyesi en az %25 olmalıdır.

Ö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ırarak karşılaştırmanın durdurulmasını önlemek için hata türünü, virgül ile ayrılmış bir listede enstrümantasyon 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"
    }
}

Groovy

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

Hataları komut satırından da engelleyebilirsiniz:

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

Hataların bastırılması, karşılaştırmanın yanlış yapılandırılmış bir durumda çalışmasını sağlar ve karşılaştırmanın çıkışı, test adlarının başına hatanın eklenmesi yoluyla kasıtlı olarak yeniden adlandırılır. Örneğin, önceki snippet'te engellemeyle birlikte hata ayıklama yapılabilir bir karşılaştırma çalıştırıldığında test adlarının başına DEBUGGABLE_ eklenir.