Mikro Karşılaştırma Yazma

Uygulama kodunuzda 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 eksiksiz 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, kodu modüllere taşımaya gerek kalmadan karşılaştırma yapmayı ve tek seferlik ölçümleri çalıştırmayı öğrenebilirsiniz. Doğru performans sonuçları için bu adımlar, uygulamanızda hata ayıklamayı devre dışı bırakmayı içerir. Bu nedenle, kaynak kontrol sisteminizde değişiklik yapmadan bunu yerel çalışan bir kopyada tutun.

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

    Modern

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

    androidTestImplementation bağımlılığı yerine implementation bağımlılığı kullanın. androidTestImplementation öğesini kullanırsanı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ıklanamayacak şekilde güncelleyin:

    Kotlin

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

    Modern

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

    Kotlin

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

    Modern

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

    Aşağıdaki kod snippet'i, Kullanılan teste bir karşılaştırmanın nasıl 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 konusunda daha fazla bilgi edinmek için Mikro Karşılaştırma sınıfı oluşturma bölümüne geçin.

Tam proje kurulumu

Bir kerelik karşılaştırmalar yerine düzenli karşılaştırmalar ayarlamak için, karşılaştırmaları kendi modüllerine ayırın. Bu, kullanıcının yapılandırmasının (ör. debuggable'in false olarak ayarlanması gibi) normal testlerden ayrı olmasını sağlamaya yardımcı olur.

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

uygulama yapısı
Şekil 1. :benchmarkable modülünde Microbenchmarks karşılaştırma kodunun kullanılmasına olanak tanıyan, :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, karşılaştırma dizini eklenir ve debuggable değeri false değerine ayarlanır.

  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ı olarak "microbenchmark" yazın.

  5. Son'u tıklayın.

Yeni kitaplık modülünü yapılandır
Ş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 kod içeren modüle androidTestImplementation ekleyin:

Kotlin

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

Modern

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

Mikro Karşılaştırma 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 aracını kullanın. Kullanıcı arayüzü kodunu karşılaştırmak için @UiThreadTest değerini 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 iterasyonunda çalıştırmanız gereken kodu 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ğunun içinde ve runWithTimingDisabled içinde yapılan iş miktarını en aza indirmeye çalışın. measureRepeated bloku birden fazla kez çalıştırılır ve karşılaştırmanın çalışması için gereken toplam süreyi etkileyebilir. Bir karşılaştırmanın bazı sonuçlarını doğrulamanız gerekirse karşılaştırmanın her yinelemesini uygulamak yerine son sonucu iddia edebilirsiniz.

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

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.

Mikro Karşılaştırma Çalıştırın
Şekil 3. Bir test sınıfının yanındaki oluk işlemini kullanarak Microbenchmark testini çalıştırın.

Alternatif olarak, belirtilen Gradle modülünden 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 için:

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

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

Başarılı bir Mikro karşılaştırma çalıştırmasından sonra, metrikler doğrudan Android Studio'da görüntülenir ve ek metriklerin ve cihaz bilgilerinin yer aldığı tam karşılaştırma raporu JSON biçiminde sunulur.

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/

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

Yapılandırma hataları

Kitaplık, projenizin ve ortamınızın doğru performans gösterecek ş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. Emülatörler desteklenmemektedir.
  • 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ırmada hatalı ölçümlerden caydırmak için bir hata bildirilir.

Belirli hata türlerini uyarı olarak gizlemek ve karşılaştırmayı durdurmaları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"
    }
}

Modern

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

Hataları komut satırından 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ışmasına olanak tanır ve karşılaştırmanın çıkışı, hatalı test adları önceden kasıtlı olarak yeniden adlandırılır. Örneğin, hata ayıklaması yapılabilir bir karşılaştırma önceki snippet'teki gizleme ile çalıştırdığınızda test adlarının başına DEBUGGABLE_ eklenir.