Menjalankan benchmark dalam Continuous Integration

Tetap teratur dengan koleksi Simpan dan kategorikan konten berdasarkan preferensi Anda.

Anda dapat menjalankan benchmark dalam Continuous Integration (CI) untuk melacak performa seiring waktu, dan mengenali regresi performa (atau peningkatan) bahkan sebelum aplikasi dirilis. Halaman ini memberikan informasi dasar tentang benchmark dalam CI.

Sebelum mulai menggunakan benchmark di CI, pertimbangkan perbedaan antara merekam dan mengevaluasi hasil dengan pengujian reguler.

Hasil fuzi

Meskipun benchmark adalah pengujian berinstrumen, hasilnya bukan hanya lulus/gagal. Benchmark memberikan pengukuran waktu untuk perangkat tertentu yang digunakan untuk menjalankannya. Membuat grafik hasil seiring waktu memungkinkan Anda memantau perubahan dan mengamati derau dalam sistem pengukuran.

Gunakan perangkat aktual

Benchmark harus dijalankan di perangkat Android fisik. Meskipun benchmark dapat berjalan di emulator, hal ini sangat tidak disarankan karena tidak akan mewakili pengalaman pengguna yang realistis dan akan memberikan angka yang terikat dengan kemampuan OS dan hardware host. Pertimbangkan penggunaan perangkat sungguhan atau layanan yang memungkinkan Anda menjalankan pengujian di perangkat sungguhan, seperti Firebase Test Lab.

Menjalankan benchmark

Menjalankan benchmark sebagai bagian dari pipeline CI mungkin berbeda dengan menjalankannya secara lokal dari Android Studio. Secara lokal, Anda biasanya akan menjalankan pengujian integrasi Android dengan satu tugas connectedCheck Gradle. Tugas ini secara otomatis mem-build APK dan menguji APK Anda serta menjalankan pengujian pada perangkat yang saat ini terhubung. Saat berjalan di CI, alur ini biasanya perlu dibagi menjadi fase terpisah.

Build

Untuk library Microbenchmark, jalankan tugas Gradle assemble[VariantName]AndroidTest, yang membuat APK pengujian berisi kode aplikasi serta kode yang diuji.

Atau, library Macrobenchmark mengharuskan Anda membuat APK target dan APK pengujian secara terpisah. Oleh karena itu, jalankan tugas Gradle :app:assemble[VariantName] dan :macrobenchmark:assemble[VariantName].

Instal dan jalankan

Langkah-langkah ini biasanya dilakukan tanpa perlu menjalankan tugas Gradle. Perhatikan bahwa pengujian tersebut mungkin diabstrakkan, bergantung pada apakah Anda menggunakan layanan yang memungkinkan Anda menjalankan pengujian pada perangkat sungguhan.

Untuk penginstalan, gunakan perintah adb install dan tentukan APK pengujian (atau APK target).

Jalankan perintah instrumen adb shell am untuk menjalankan semua benchmark.

adb shell am instrument -w com.example.benchmark/androidx.benchmark.junit4.AndroidBenchmarkRunner

Perhatikan bahwa saat menggunakan library Macrobenchmark, gunakan androidx.test.runner.AndroidJUnitRunner reguler sebagai runner instrumentasi.

Anda dapat meneruskan argumen instrumentasi yang sama seperti dalam konfigurasi Gradle menggunakan argumen -e. Untuk semua opsi argumen instrumentasi, periksa halaman untuk Microbenchmark atau Macrobenchmark.

Misalnya, Anda dapat menetapkan argumen dryRunMode untuk menjalankan microbenchmark sebagai bagian dari proses verifikasi permintaan pull. Dengan mengaktifkan flag ini, microbenchmark hanya berjalan dalam satu loop yang memungkinkan untuk memverifikasi bahwa proses tersebut berjalan dengan benar, tetapi tidak membutuhkan waktu yang terlalu lama untuk dijalankan.

adb shell am instrument -w -e "androidx.benchmark.dryRunMode.enable" "true" com.example.benchmark/androidx.benchmark.junit4.AndroidBenchmarkRunner

Lihat Menjalankan pengujian dengan ADB untuk informasi selengkapnya tentang cara menjalankan uji instrumentasi dari command line.

Mengunci frekuensi CPU

Plugin Gradle Microbenchmark memberikan perintah ./gradlew lockClocks untuk mengunci frekuensi CPU perangkat yang telah di-root. Hal ini berguna untuk memastikan stabilitas saat Anda memiliki akses ke perangkat yang telah di-root, seperti build "userdebug". Anda dapat mereplika ini menggunakan skrip shell lockClocks.sh, yang tersedia di sumber library.

Anda dapat menjalankan skrip tersebut secara langsung dari host Linux atau Mac, atau mengirimnya ke perangkat dengan beberapa perintah adb:

adb push path/lockClocks.sh /data/local/tmp/lockClocks.sh
adb shell /data/local/tmp/lockClocks.sh
adb shell rm /data/local/tmp/lockClocks.sh

Jika Anda menjalankan skrip shell secara langsung di host, host akan mengirimkan perintah ini ke perangkat yang tersambung.

Untuk informasi selengkapnya tentang alasan pentingnya mengunci frekuensi CPU, periksa cara mendapatkan benchmark yang konsisten.

Mengumpulkan hasil

Library benchmark menghasilkan pengukuran di JSON, beserta rekaman aktivitas pembuatan profil ke direktori di perangkat Android setelah setiap benchmark dijalankan. Library Macrobenchmark menghasilkan beberapa file detail migrasi perfetto: satu file per iterasi pengukuran untuk setiap loop MacrobenchmarkRule.measureRepeated. Namun, Microbenchmark hanya membuat satu file detail migrasi untuk semua iterasi dari setiap BenchmarkRule.measureRepeated. File detail migrasi pembuatan profil juga akan dikeluarkan ke direktori yang sama ini.

Menyimpan dan menemukan file

Jika Anda menjalankan benchmark dengan Gradle, file ini akan otomatis disalin ke direktori output komputer host Anda di build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/. Jika berjalan langsung dengan perintah adb, Anda harus menariknya secara manual. Secara default, laporan disimpan di perangkat dalam direktori media dari penyimpanan eksternal aplikasi yang diuji. Untuk memudahkan, library mencetak jalur file ke Logcat. Perhatikan bahwa folder output mungkin berbeda, tergantung pada versi Android mana benchmark dijalankan.

Benchmark: writing results to /storage/emulated/0/Android/media/com.example.macrobenchmark/com.example.macrobenchmark-benchmarkData.json

Anda juga dapat mengonfigurasi lokasi tempat laporan benchmark disimpan pada perangkat menggunakan argumen instrumentasi additionalTestOutputDir. Folder ini harus dapat ditulis oleh aplikasi Anda.

adb shell am instrument -w -e additionalTestOutputDir /sdcard/Download/ com.example.benchmark/androidx.benchmark.junit4.AndroidBenchmarkRunner

Di Android 10 (API level 29) dan yang lebih tinggi, pengujian aplikasi Anda berjalan di sandbox penyimpanan secara default yang mencegah aplikasi Anda mengakses file di luar direktori khusus aplikasi. Agar dapat menyimpan ke beberapa direktori global (seperti /sdcard/Download), Anda dapat meneruskan argumen instrumentasi berikut:

-e no-isolated-storage true

Anda juga harus secara eksplisit mengizinkan opsi penyimpanan lama dalam manifes benchmark Anda:

<application android:requestLegacyExternalStorage="true" ... >

Untuk informasi selengkapnya, lihat Memilih tidak menggunakan penyimpanan terbatas untuk sementara.

Mengambil file

Untuk mendapatkan file yang dihasilkan dari perangkat, Anda dapat menggunakan perintah adb pull, yang menarik file yang ditentukan ke direktori saat ini pada host Anda.

adb pull /storage/emulated/0/Android/media/com.example.macrobenchmark/com.example.macrobenchmark-benchmarkData.json

Untuk mengambil semua benchmarkData dari folder yang ditentukan, periksa cuplikan berikut:

# The following command pulls all files ending in -benchmarkData.json from the directory
# hierarchy starting at the root /storage/emulated/0/Android.
adb shell find /sdcard/Download -name "*-benchmarkData.json" | tr -d '\r' | xargs -n1 adb pull

Perhatikan bahwa file detail migrasi (.trace atau .perfetto-trace) disimpan di folder yang sama dengan benchmarkData.json, sehingga Anda dapat mengumpulkannya dengan cara yang sama.

Contoh data benchmark

Library benchmark menghasilkan file JSON yang berisi informasi tentang perangkat tempat benchmark dijalankan dan benchmark sebenarnya yang dijalankannya. Cuplikan berikut mewakili file JSON yang dihasilkan.

{
    "context": {
        "build": {
            "brand": "google",
            "device": "blueline",
            "fingerprint": "google/blueline/blueline:12/SP1A.210812.015/7679548:user/release-keys",
            "model": "Pixel 3",
            "version": {
                "sdk": 31
            }
        },
        "cpuCoreCount": 8,
        "cpuLocked": false,
        "cpuMaxFreqHz": 2803200000,
        "memTotalBytes": 3753299968,
        "sustainedPerformanceModeEnabled": false
    },
    "benchmarks": [
        {
            "name": "startup",
            "params": {},
            "className": "com.example.macrobenchmark.startup.SampleStartupBenchmark",
            "totalRunTimeNs": 4975598256,
            "metrics": {
                "timeToInitialDisplayMs": {
                    "minimum": 347.881076,
                    "maximum": 347.881076,
                    "median": 347.881076,
                    "runs": [
                        347.881076
                    ]
                }
            },
            "sampledMetrics": {},
            "warmupIterations": 0,
            "repeatIterations": 3,
            "thermalThrottleSleepSeconds": 0
        }
    ]
}

Referensi lainnya