Makrobenchmark yazın

Uygulama başlatma ve LazyColumn kaydırma veya animasyon çalıştırma gibi karmaşık kullanıcı arayüzü işlemleri de dahil olmak üzere uygulamanızın daha büyük kullanım alanlarını test etmek için Macrobenchmark kitaplığını kullanın. Kodunuzun daha küçük alanlarını test etmek istiyorsanız Microbenchmark'a bakın. Bu sayfada, Macrobenchmark kitaplığının nasıl ayarlanacağı gösterilmektedir.

Kitaplık, karşılaştırma sonuçlarını Android Studio konsoluna ve daha fazla ayrıntı içeren bir JSON dosyasına aktarır. Ayrıca, Android Studio'da yükleyip analiz edebileceğiniz izleme dosyaları da sağlar.

Macrobenchmark kitaplığını, Sürekli Entegrasyonda Karşılaştırma bölümünde açıklandığı gibi sürekli entegrasyon (CI) ortamında kullanın.

Temel Profiller oluşturmak için Macrobenchmark'ı kullanabilirsiniz. Öncelikle Macrobenchmark kitaplığını kurun, ardından temel profil oluşturabilirsiniz.

Macrobenchmark, Jetpack Compose ile oluşturulan kullanıcı arayüzlerini test etmek için önerilen araçtır. Oluşturma düğümlerinizle etkileşim kuran UI Automator testlerini nasıl yazacağınızı öğrenmek için Birlikte çalışabilirlik bölümüne bakın.

Proje ayarlama

Macrobenchmark'ı Android Studio'nun en yeni sürümüyle kullanmanızı öneririz.

Macrobenchmark modülünü ayarlama

Makro karşılaştırmalar, uygulamanızın kodundan ayrı bir com.android.test modülü gerektirir. Bu modül, uygulamanızı ölçen testleri çalıştırmaktan sorumludur.

Android Studio'da, Macrobenchmark modülünün kurulumunu basitleştiren bir şablon bulunur. Karşılaştırma modülü şablonu, projenizde uygulama modülü tarafından oluşturulan uygulamayı ölçmek için otomatik olarak bir modül oluşturur. Bu modül, örnek bir başlangıç karşılaştırması içerir.

Modül şablonunu kullanarak yeni bir modül oluşturmak için aşağıdakileri yapın:

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

  2. Şablonlar bölmesinden Karşılaştırma'yı seçin. Yeni Macrobenchmark modülü için paket ve modül adının yanı sıra hedef uygulamayı (yani karşılaştırması yapılacak uygulamayı) özelleştirebilirsiniz.

  3. Son'u tıklayın.

Karşılaştırma Modülü şablonu.
Şekil 1. Karşılaştırma modülü şablonu.

Uygulamayı kurma

Macrobenchmark'ın hedefi olarak bilinen bir uygulamayı karşılaştırmak için uygulamanın profileable olması gerekir. Bu sayede, performansı etkilemeden ayrıntılı izleme bilgileri okunabilir. Modül sihirbazı, <profileable> etiketini uygulamanın AndroidManifest.xml dosyasına otomatik olarak ekler.

Hedef uygulamanın, Macrobenchmark kitaplığının profil yakalama ve sıfırlama ile gölgelendirici önbelleği temizleme işlemlerini etkinleştirmek için ihtiyaç duyduğu ProfilerInstaller 1.3 veya sonraki bir sürümü içerdiğinden emin olun.

Karşılaştırmalı değerlendirme yapılan uygulamayı, yayınlanan sürüme veya üretim sürümüne mümkün olduğunca yakın olacak şekilde yapılandırın. Uygulamayı hata ayıklanamaz olarak ve tercihen sadeleştirme etkin olacak şekilde ayarlayın. Bu, performansı artırır. Bunu genellikle, sürüm varyantının aynı şekilde çalışan ancak hata ayıklama anahtarlarıyla yerel olarak imzalanmış bir kopyasını oluşturarak yaparsınız. Alternatif olarak, Gradle'ın bunu sizin için yapmasını sağlamak üzere initWith kullanabilirsiniz:

Kotlin

buildTypes {
    getByName("release") {
        isMinifyEnabled = true
        isShrinkResources = true
        proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"))
    }

    create("benchmark") {
        initWith(getByName("release"))
        signingConfig = signingConfigs.getByName("debug")
    }
}

Modern

buildTypes {
    release {
        isMinifyEnabled = true
        isShrinkResources = true
        proguardFiles(
            getDefaultProguardFile("proguard-android-optimize.txt"),
            "keep-rules.pro"
        )
        // In real app, this would use its own release keystore
        signingConfig = signingConfigs.getByName("debug")
        baselineProfile.automaticGenerationDuringBuild = true
    }
}

Karşılaştırmanın çalıştırılmasıyla uygulamanızın doğru varyantının hem derlenmesini hem de test edilmesini sağlamak için Şekil 2'de gösterildiği gibi aşağıdakileri yapın:

  1. Gradle senkronizasyonu gerçekleştirin.
  2. Build Variants (Derleme Değişkenleri) panelini açın.
  3. Hem uygulamanın hem de Macrobenchmark modülünün karşılaştırma varyantını seçin.
Karşılaştırma varyantını seçin.
Şekil 2. Karşılaştırma varyantını seçin.

(İsteğe bağlı) Çok modüllü uygulama oluşturma

Uygulamanızda birden fazla Gradle modülü varsa derleme komut dosyalarınızın hangi derleme değişkenini derleyeceğini bildiğinden emin olun. matchingFallbacks özelliğini :macrobenchmark ve :app modüllerinizin benchmark derleme türüne ekleyin. Gradle modüllerinizin geri kalanı öncekiyle aynı yapılandırmaya sahip olabilir.

Kotlin

create("benchmark") {
    initWith(getByName("release"))
    signingConfig = signingConfigs.getByName("debug")

    matchingFallbacks += listOf("release")
 }

Modern

benchmark {
    initWith buildTypes.release
    signingConfig signingConfigs.debug

    matchingFallbacks = ['release']
 }

Bu işlem yapılmazsa yeni eklenen benchmark derleme türü, derlemenin başarısız olmasına neden olur ve aşağıdaki hata mesajını verir:

> Could not resolve project :shared.
     Required by:
         project :app
      > No matching variant of project :shared was found.
      ...

Projenizdeki derleme değişkenlerini seçerken :app ve :macrobenchmark modülleri için benchmark, uygulamanızdaki diğer modüller için ise release seçeneğini belirleyin (Şekil 3'te gösterildiği gibi):

Sürüm ve karşılaştırma derleme türleri seçili olan çok modüllü proje için karşılaştırma varyantları.
Şekil 3. Sürüm ve karşılaştırma derleme türleri seçili olan çok modüllü proje için karşılaştırma varyantları.

Daha fazla bilgi için Varyant eşleştirme ile ilgili derleme hatalarını çözme başlıklı makaleyi inceleyin.

(İsteğe bağlı) Ürün türlerini ayarlama

Uygulamanızda birden fazla ürün türü ayarlanmışsa :macrobenchmark modülünü, uygulamanızın hangi ürün türünü derleyip karşılaştıracağını bilecek şekilde yapılandırın.

Bu sayfadaki örneklerde, aşağıdaki snippet'te gösterildiği gibi :app modülündeki iki ürün türü (demo ve production) kullanılmaktadır:

Kotlin

flavorDimensions += "environment"
productFlavors {
    create("demo") {
        dimension = "environment"
        // ...
    }
    create("production") {
        dimension = "environment"
        // ...
    }
}

Modern

flavorDimensions 'environment'
productFlavors {
    demo {
        dimension 'environment'
        // ...
    }

    production {
        dimension 'environment'
        // ...
    }
}

Bu yapılandırma olmadan, birden fazla Gradle modülünün neden olduğu hataya benzer bir derleme hatası alabilirsiniz:

Could not determine the dependencies of task ':macrobenchmark:connectedBenchmarkAndroidTest'.
> Could not determine the dependencies of null.
   > Could not resolve all task dependencies for configuration ':macrobenchmark:benchmarkTestedApks'.
      > Could not resolve project :app.
        Required by:
            project :macrobenchmark
         > The consumer was configured to find a runtime of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'benchmark', attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '7.3.0'. However we cannot choose between the following variants of project :app:
             -   demoBenchmarkRuntimeElements
             -   productionBenchmarkRuntimeElements
           All of them match the consumer attributes:
           ...

Aşağıdaki iki bölümde, birden fazla ürün türüyle karşılaştırmayı yapılandırma yöntemleri açıklanmaktadır.

missingDimensionStrategy kullanma

:macrobenchmark modülünün defaultConfig bölümünde missingDimensionStrategy belirtildiğinde derleme sistemi, yedek olarak tür boyutunu kullanır. Modülde bulamazsanız hangi boyutların kullanılacağını belirtin. Aşağıdaki örnekte, varsayılan boyut olarak production varyantı kullanılmıştır:

Kotlin

defaultConfig {
    missingDimensionStrategy("environment", "production")
}

Modern

defaultConfig {
    missingDimensionStrategy "environment", "production"
}

Bu sayede :macrobenchmark modülü, yalnızca belirtilen ürün türünü derleyip karşılaştırabilir. Bu, yalnızca bir ürün türünün karşılaştırma için uygun yapılandırmaya sahip olduğunu bildiğiniz durumlarda faydalıdır.

:macrobenchmark modülünde ürün türlerini tanımlama

Diğer ürün türlerini derlemek ve karşılaştırmak istiyorsanız bunları :macrobenchmark modülünde tanımlayın. :app modülündekine benzer şekilde belirtin ancak productFlavors değerini yalnızca bir dimension değerine atayın. Başka bir ayar gerekmez:

Kotlin

flavorDimensions += "environment"
productFlavors {
    create("demo") {
        dimension = "environment"
    }
    create("production") {
        dimension = "environment"
    }
}

Modern

flavorDimensions 'environment'
productFlavors {
    demo {
        dimension 'environment'
    }

    production {
        dimension 'environment'
    }
}

Projeyi tanımlayıp senkronize ettikten sonra, Şekil 4'te gösterildiği gibi Derleme Değişkenleri panelinden ilgili derleme değişkenini seçin:

productionBenchmark ve release seçili olarak ürün türlerini gösteren proje için referans varyantlar.
Şekil 4. "productionBenchmark" ve "release" seçili olarak gösterilen ürün türlerini içeren projenin varyantlarını karşılaştırın.

Daha fazla bilgi için Varyant eşleştirme ile ilgili derleme hatalarını çözme başlıklı makaleyi inceleyin.

Macrobenchmark sınıfı oluşturma

Karşılaştırma testi, Macrobenchmark kitaplığındaki MacrobenchmarkRule JUnit4 kural API'si aracılığıyla sağlanır. Bu sınıf, hedef uygulamanın nasıl çalıştırılacağı ve karşılaştırılacağıyla ilgili çeşitli koşulları belirtmenize olanak tanıyan bir measureRepeated yöntemi içerir.

En azından hedef uygulamanın packageName, ölçmek istediğiniz metrics ve karşılaştırmanın kaç iterations çalıştırılması gerektiğini belirtmeniz gerekir.

Kotlin

@LargeTest
@RunWith(AndroidJUnit4::class)
class SampleStartupBenchmark {
    @get:Rule
    val benchmarkRule = MacrobenchmarkRule()

    @Test
    fun startup() = benchmarkRule.measureRepeated(
        packageName = TARGET_PACKAGE,
        metrics = listOf(StartupTimingMetric()),
        iterations = DEFAULT_ITERATIONS,
    ) {
        // starts default launch activity
        uiAutomator { startApp(TARGET_PACKAGE) }
    }
}

Karşılaştırmanızı özelleştirmeyle ilgili tüm seçenekler için Karşılaştırmaları özelleştirme bölümüne bakın.

Compose kullanıcı arayüzü etkileşimlerini karşılaştırma

Önceki örnekte uygulama başlatma ölçülürken genellikle kaydırma sırasında kare düşüşleri (takılma) gibi kullanıcı arayüzü performansını ölçmek istersiniz.

Bir Jetpack Compose uygulamasını karşılaştırmak için (ör. LazyColumn kaydırırken FrameTimingMetric ölçmek için) aşağıdaki snippet'te gösterildiği gibi doğrudan Compose düğümlerinizle etkileşim kurmak üzere UI Automator'ı kullanabilirsiniz.

@LargeTest
@RunWith(AndroidJUnit4::class)
class ComposeScrollBenchmark {
    @get:Rule
    val benchmarkRule = MacrobenchmarkRule()

    @Test
    fun scrollLazyColumn() = benchmarkRule.measureRepeated(
        packageName = "com.example.compose.app",
        metrics = listOf(FrameTimingMetric()),
        iterations = 5,
        startupMode = StartupMode.WARM,
        setupBlock = { pressHome() }
    ) {
        startActivityAndWait()

        // Find the Compose node using the testTag defined in your app
        val lazyColumn = device.findObject(By.res("my_lazy_column"))

        // Simulate a scroll gesture to measure FrameTimingMetric
        lazyColumn.setGestureMargin(device.displayWidth / 5)
        lazyColumn.fling(Direction.DOWN)
    }
}

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

Uygulamanızın cihazınızdaki performansını ölçmek için testi Android Studio'dan çalıştırın. Karşılaştırmaları, Şekil 5'te gösterildiği gibi test sınıfınızın veya yönteminizin yanındaki gutter işlemini kullanarak diğer @Test gibi çalıştırabilirsiniz.

Test sınıfının yanındaki gutter işlemini kullanarak Macrobenchmark'ı çalıştırın.
Şekil 5. Test sınıfının yanındaki gutter işlemiyle Macrobenchmark'ı çalıştırın.

Ayrıca, connectedCheck komutunu çalıştırarak bir Gradle modülündeki tüm karşılaştırmaları komut satırından çalıştırabilirsiniz:

./gradlew :macrobenchmark:connectedCheck

Aşağıdaki komutu çalıştırarak tek bir test çalıştırabilirsiniz:

./gradlew :macrobenchmark:connectedCheck -P android.testInstrumentationRunnerArguments.class=com.example.macrobenchmark.startup.SampleStartupBenchmark#startup

Sürekli entegrasyonda karşılaştırmaların nasıl çalıştırılacağı ve izleneceği hakkında bilgi için Sürekli Entegrasyonda Karşılaştırma bölümüne bakın.

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

Başarılı bir karşılaştırma çalıştırmasından sonra metrikler doğrudan Android Studio'da gösterilir ve CI kullanımı için bir JSON dosyasında çıktı olarak verilir. Ölçülen her iterasyon, ayrı bir sistem izi yakalar. Bu izleme sonuçlarını, Şekil 6'da gösterildiği gibi Test Sonuçları bölmesindeki bağlantıları tıklayarak açabilirsiniz:

Macrobenchmark başlatma sonuçları.
Şekil 6. Macrobenchmark başlatma sonuçları.

İzleme yüklendiğinde Android Studio, analiz edilecek işlemi seçmenizi ister. Seçim, Şekil 7'de gösterildiği gibi hedef uygulama işlemiyle önceden doldurulur:

Studio izleme işlemi seçimi.
Şekil 7. Studio izleme işlemi seçimi.

İzleme dosyası yüklendikten sonra Studio, sonuçları CPU Profiler aracında gösterir:

Studio izleme.
Şekil 8. Studio izi.

JSON raporları ve 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/

İzleme dosyalarına manuel olarak erişme

İzleme dosyasını analiz etmek için Perfetto aracını kullanmak istiyorsanız ek adımlar uygulamanız gerekir. Perfetto, izleme sırasında cihazda gerçekleşen tüm işlemleri incelemenize olanak tanır. Android Studio'nun CPU Profiler'ı ise incelemeyi tek bir işlemle sınırlandırır.

Testleri Android Studio'dan veya Gradle komut satırından çağırırsanız izleme dosyaları 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/TrivialStartupBenchmark_startup[mode=COLD]_iter002.perfetto-trace

İzleme dosyası ana sisteminizde olduğunda, menüden Dosya > Aç'ı seçerek dosyayı Android Studio'da açabilirsiniz. Bu, önceki bölümde gösterilen profil oluşturma aracı görünümünü gösterir.

Yapılandırma hataları

Uygulama yanlış yapılandırılmışsa (hata ayıklanabilir veya profili oluşturulamaz) Macrobenchmark, yanlış veya eksik bir ölçüm bildirmek yerine hata döndürür. androidx.benchmark.suppressErrors bağımsız değişkeniyle bu hataları gizleyebilirsiniz.

Macrobenchmark, bir emülatörü veya düşük pilli bir cihazı ölçmeye çalışırken de hata döndürür. Bu durum, çekirdek kullanılabilirliğini ve saat hızını tehlikeye atabilir.

Karşılaştırmaları özelleştirme

measureRepeated işlevi, kitaplığın hangi metrikleri topladığını, uygulamanızın nasıl başlatılıp derlendiğini veya karşılaştırmanın kaç iterasyon çalıştırdığını etkileyen çeşitli parametreleri kabul eder.

Metrikleri yakalama

Metrikler, karşılaştırmalarınızdan elde edilen ana bilgi türüdür. Aşağıdaki metrikler kullanılabilir:

Metrikler hakkında daha fazla bilgi için Makro karşılaştırma metriklerini yakalama başlıklı makaleyi inceleyin.

Özel etkinliklerle izleme verilerini iyileştirme

Uygulamanızı, izleme raporunun geri kalanıyla birlikte görülen ve uygulamanıza özgü sorunları belirlemenize yardımcı olabilecek özel izleme etkinlikleriyle donatmak faydalı olabilir. Özel izleme etkinlikleri oluşturma hakkında daha fazla bilgi edinmek için Özel etkinlikleri tanımlama başlıklı makaleyi inceleyin.

CompilationMode

Makro karşılaştırmalar, uygulamanın ne kadarının DEX bayt kodundan (APK içindeki bayt kodu biçimi) makine diline (önceden derlenmiş C++'a benzer) önceden derlenmesi gerektiğini tanımlayan bir CompilationMode belirtebilir.

Makro karşılaştırmalar varsayılan olarak CompilationMode.DEFAULT ile çalıştırılır. Bu, Android 7 (API düzeyi 24) ve sonraki sürümlere (varsa) bir Temel Profil yükler. Android 6 (API düzeyi 23) veya daha eski bir sürüm kullanıyorsanız derleme modu, varsayılan sistem davranışı olarak APK'yı tamamen derler.

Hedef uygulama hem Temel Profil hem de ProfileInstaller kitaplığını içeriyorsa Temel Profil yükleyebilirsiniz.

Android 7 ve sonraki sürümlerde, farklı düzeylerde önceden (AOT) derleme veya JIT önbelleğe alma işlemlerini taklit etmek için cihaz üzerinde ön derleme miktarını etkileyecek şekilde CompilationMode değerini özelleştirebilirsiniz. CompilationMode.Full, CompilationMode.Partial, CompilationMode.None ve CompilationMode.Ignore sayfalarına göz atın.

Bu özellik, ART derleme komutları üzerine kurulmuştur. Her karşılaştırma, başlamadan önce profil verilerini temizler. Bu sayede karşılaştırmalar arasında karışıklık yaşanmaz.

StartupMode

Etkinlik başlatma işlemi gerçekleştirmek için önceden tanımlanmış bir başlatma modu iletebilirsiniz: COLD, WARM veya HOT. Bu parametre, etkinliğin nasıl başlatılacağını ve testin başındaki işlem durumunu değiştirir.

Başlatma türleri hakkında daha fazla bilgi edinmek için Uygulama başlatma süresi başlıklı makaleyi inceleyin.

Örnekler

  • GitHub'daki deponun Macrobenchmark Örneği'nde örnek bir proje bulabilirsiniz.
  • Jetpack Compose ve görünümlerde başlatma ve kaydırma performansını ölçmek için Macrobenchmark'ın kullanıldığı gerçek bir örnek olay için Hero karşılaştırmaları başlıklı makaleyi inceleyin.

Geri bildirim gönderin

Jetpack Macrobenchmark ile ilgili sorunları bildirmek veya özellik istekleri göndermek için herkese açık Issue Tracker'a bakın.