Mengoptimalkan aplikasi Android memerlukan visibilitas mendalam ke dalam alur kerja serentak dan penangguhan coroutine.
Meskipun pembuatan profil lokal menawarkan snapshot yang berguna, menskalakan insight ini ke produksi tanpa overhead tetap menjadi tantangan.
Sesi ini memberikan blueprint arsitektur untuk feedback loop performa berkelanjutan.
androidx.tracing 2.0: Menukar backend secara dinamis dan menyebarkan konteks coroutine (alur Perfetto) di seluruh thread.
Instrumentasi Cerdas: Gunakan pelacakan ART lokal untuk menemukan hotspot, lalu otomatiskan injeksi titik pelacakan overhead rendah.
Macrobenchmarking: Lacak regresi dan verifikasi peningkatan performa di perangkat fisik dalam CI.
Pelacakan Lapangan: Lakukan lebih dari sekadar pelacakan lokal dan CI, dengan ProfilingManager.
traceCoroutine atau meneruskan token propagasi ke kode berbasis callback.Transkrip
Rahul Ravikumar
Selamat siang, semuanya.
Nama saya Rahul.
Saya adalah engineer di tim Android Developer Experience.
Saya berfokus pada performa aplikasi dan library, dan pembahasan ini adalah tentang pelacakan.
Sebelum kita membahas pelacakan secara mendalam, saya ingin menetapkan beberapa kosakata umum agar Anda dapat mengikutinya.
Jadi, setiap kali saya menyebut pelacakan dalam pembahasan ini, yang saya maksud adalah pelacakan eksplisit, yaitu menginstrumentasikan kode secara manual agar Anda tahu apa yang dilakukan aplikasi.
Kami tidak membahas profiler otomatis yang akan kami bahas.
Jadi, pelacakan manual adalah seni meninggalkan jejak di code base, sehingga Anda dapat memahaminya nanti saat mengalami masalah performa atau masalah lainnya.
Biasanya, cara ini jauh lebih baik daripada log.
Jadi, kami tidak tahu apakah Anda pernah melihat output Logcat dari aplikasi besar.
Biasanya, log ini berupa teks yang sangat panjang dan sulit dipahami dengan mudah.
Di sisi lain, pelacakan jauh lebih baik.
Visualisasinya lebih mudah.
Anda memiliki durasi.
Anda memiliki beberapa struktur.
Anda memiliki beberapa alat, sehingga Anda bahkan dapat memilah dan melihat dengan tepat apa yang terjadi dan kapan.
Jadi, ini jauh lebih baik.
Dan Anda dapat, Anda tahu, mengarahkan agen Anda ke trace dan mengatakan, ajukan pertanyaan.
Anda dapat menggunakan alat seperti Trace Processor, tolok ukur, dan bahkan mengonversi rekaman aktivitas menjadi metrik.
Jadi, ini semua adalah hal yang dapat Anda lakukan dengan rekaman aktivitas yang sulit dilakukan dengan Logcat.
Di sisi lain, pembuatan profil, dan yang saya maksud adalah pembuatan profil otomatis, biasanya merupakan respons terhadap masalah yang Anda ketahui.
Misalnya, Anda mungkin melihat bahwa aplikasi Anda dimulai dengan lambat, atau ada sesuatu yang tersendat, dan Anda ingin mempersempitnya, serta ingin mencari tahu apa yang terjadi.
Pada tahap ini, jika Anda belum memiliki pelacakan manual untuk membantu Anda, di sinilah pembuatan profil otomatis berperan.
Anda mungkin menggunakan sesuatu seperti pelacakan metode ART, yang menginstrumentasikan setiap entri dan keluar metode.
Atau, Anda mungkin melihat pengambilan sampel stack dengan alat seperti Simpleperf.
Jadi, daripada menggunakan setiap entri dan keluar metode serta memiliki overhead yang tinggi, Anda melihat sampel stack panggilan, dan melihat apa yang ada di jalur panas aplikasi Anda.
Sekarang tahun 2026, RAM menjadi masalah di mana-mana, jadi Anda mungkin melihat memori, kebocoran memori, dan profil heap.
Jadi, ini adalah profiler lain yang dapat Anda manfaatkan.
Anda tahu, Anda dapat melihat jalur retensi heap.
Anda dapat melihat kode apa yang mengalokasikan memori, dan itu semua adalah jenis analisis yang dapat Anda lakukan dengan alat ini.
Ya.
Sekarang, kita memiliki kosakata tersebut.
Sekarang, mari kita bahas alasan kami membuat library baru.
API Pelacakan, API 1.0 awalnya diperkenalkan di Android Jelly Bean.
Itu terjadi pada tahun 2012.
Itu lebih dari 14 tahun yang lalu.
Sejak saat itu, API belum berkembang sebanyak yang Anda kira.
Kami menambahkan beberapa ekstensi.
Peristiwa dan penghitung asinkron ditambahkan di Android 10.
Itu terjadi pada tahun 2019.
Dan selesai.
API ini belum berkembang sejak saat itu.
Namun, ekosistemnya telah berkembang pesat.
Jadi, pelacakan platform telah meningkat pesat, tetapi tidak ada yang berdampak dalam hal penambahan API untuk Anda.
Hal itulah yang ingin kami ubah.
Masalah besar lainnya adalah pelacakan memiliki backend pelacakan tetap di 1.0, yang berarti setiap kali Anda menambahkan bagian pelacakan dalam kode, bagian tersebut akan selalu berakhir di buffering pelacakan sistem.
Atrace adalah subsistem pelacakan Android yang memiliki data tersebut.
Jadi, jika Anda ingin mengambil rekaman aktivitas dan mengonversinya menjadi telemetri kolom, hal itu sangat sulit, karena sekarang, Anda harus menyadari cara atrace menyimpan data tersebut.
Format ini terdokumentasi dengan baik, tetapi mungkin sulit dipahami.
Jadi, itulah yang ingin kami perbaiki.
Jadi, kami ingin memberi Anda alat untuk membawa data pelacakan ke mana pun Anda mau.
Kami juga memiliki batasan dalam pelacakan 1.0, yaitu label dibatasi hingga 128 karakter.
Mungkin pembatasan itu masuk akal pada tahun 2012, tetapi pada tahun 2026, hal itu tampaknya agak aneh.
Yang lebih buruk adalah Anda juga tidak dapat menambahkan metadata tambahan ke trace, yang akan menimbulkan masalah tambahan.
Lalu, ada overhead.
Jadi, setiap kali melacak aplikasi, Anda harus sangat menyadari overhead, karena tindakan mengamati sistem tidak boleh mengubah apa yang dilakukan sistem di balik layar.
Jadi, jika ada kondisi race yang ingin Anda reproduksi, pelacakan tidak boleh menghilangkan kondisi race tersebut.
Jadi, Anda harus memastikan bahwa Anda mempertahankan semua semantik yang Anda lakukan.
Tracing 1.0 memiliki overhead yang relatif tinggi, dan kami ingin meningkatkannya.
Oke.
Saya banyak membahas masalah.
Sekarang, mari kita lihat beberapa masalah secara visual dan lihat bagaimana masalah tersebut bertambah dalam praktiknya.
Jadi, di sini kita memiliki rekaman aktivitas Perfetto.
Ini untuk aplikasi, com.example.app.
Kita memiliki thread utama, dan kita memiliki satu slice yang disebut initializeComponent.
Sekarang, idealnya, kita ingin beberapa detail lagi.
Jadi, mari kita tambahkan detail.
Jadi, sekarang kita tahu bahwa initializeComponent memanggil performInitialize.
Kita masih belum tahu komponen apa yang sedang diinisialisasi.
Sekarang, satu-satunya alat di tool belt kita dengan Tracing 1 adalah nama, jadi kita menambahkannya ke nama slice.
Ingat, nama slice pelacakan dibatasi hingga 128 karakter, sehingga akan dipotong dalam pelacakan Anda.
Sekarang, selain masalah tersebut, overhead pemotongan juga menjadi overhead yang Anda alami saat melakukan pelacakan.
Jadi, sekarang Anda akan mengalami masalah ini dengan cukup cepat.
Jadi, ini adalah sesuatu yang sangat ingin kami perbaiki.
Anda telah melihat rekaman aktivitas Perfetto, dan Anda telah melihat tampilannya secara visual.
Sekarang, mari kita lihat dari perspektif penulisan kode untuk memunculkan bagian rekaman aktivitas tersebut.
Sekali lagi, kita memiliki initializeComponent API.
Fungsi ini menggunakan konteks dan nama, serta memanggil performInitialize.
Sejauh ini, hasilnya bagus.
Sekarang, kita ingin menambahkan trace dengan Tracing 1.0 API, jadi Anda melakukannya dengan mengimpor androidx.tracing.trace dan menggunakan blok trace.
Anda memberinya nama.
Di sini, harganya performInitialize.
Namun, seperti yang ingin kita lakukan sebelumnya, kita ingin mengetahui nama komponen, jadi kita akan menggunakan interpolasi string Kotlin, dan kita akan menambahkan nama.
Dan inilah masalah pertamanya.
Jadi, di sini kita memiliki batas 128 karakter.
Rahul Ravikumar
Kita dapat memperbaikinya dengan Tracing 2.
Sebagai ganti androidx.tracing.trace, Anda menggunakan Tracer.
API-nya terlihat sangat mirip.
Anda memiliki Tracer.global.trace, bukan trace.
Anda memiliki kategori.
Kita akan membahas kategori secara lebih mendetail nanti, tetapi pada dasarnya, Anda memiliki nama.
Kemudian, Anda masih memiliki blok kode yang ingin Anda lacak.
Dan sekarang, Anda tidak lagi memiliki batasan 128 karakter.
Saya membahas overhead pelacakan.
Saya ingin membahasnya secara lebih mendetail dan melihat cara kami meningkatkan kualitasnya.
Di Pixel 6a yang menjalankan Android 16, tindakan menyisipkan satu bagian awal dan akhir memerlukan waktu sekitar 1.200 nanodetik.
Mungkin jumlahnya tidak banyak, tetapi jika Anda memiliki kode yang sangat aktif dan menambahkan banyak bagian rekaman aktivitas, waktu yang dihabiskan untuk itu dapat mengurangi waktu yang seharusnya digunakan aplikasi untuk merender frame.
Jadi, kami tidak ingin menyita waktu Anda.
Kami telah meningkatkan banyak hal dengan AndroidX Perfetto SDK.
Ini adalah SDK eksperimental yang kami perkenalkan untuk Pelacakan Komposisi, dan ini benar-benar meningkatkan banyak hal.
Kami tidak ingin Anda mengirimkan ini karena ini adalah Perfetto C SDK dengan binding JNI, dan C SDK berukuran sekitar 4 MB di dalam APK Anda.
Kami tidak pernah ingin Anda mengirimkan hal seperti ini.
Jadi, sekarang dengan Tracing 2, kita memiliki library yang dibuat khusus.
Kami telah meningkatkan overhead lebih banyak lagi, dan sekarang Anda akan senang mengetahui bahwa Tracing 2 7x lebih cepat, yang berarti Anda memiliki lebih banyak waktu untuk melakukan hal-hal yang ingin Anda lakukan, dan Anda tahu, infrastruktur membutuhkan lebih sedikit waktu.
Apa yang dapat dilakukan dengan hal seperti ini yang sebelumnya tidak mungkin dilakukan?
Jadi, salah satu contohnya adalah fitur pelacakan runtime Metro.
Jadi, Metro, bagi yang belum tahu, adalah library injeksi dependensi.
Library ini mendukung Multiplatform Kotlin.
Fitur ini menggunakan plugin compiler Kotlin.
Hilt menghasilkan semua kode untuk injeksi dependensi, dan terintegrasi dengan Tracing 2.0 untuk mempermudah visualisasi biaya setiap @Inject dalam kode Anda.
Berikut contohnya.
Misalnya, kita memiliki grafik aplikasi.
Di Metro, semuanya dicakupkan ke grafik, sehingga kita memiliki satu kolom, AnalyticsTracker.
Kita juga memiliki binding provides.
Kita memiliki klien jaringan dengan OkHttpClient sebagai impl, lalu implementasi AnalyticsTracker berasal dari AnalyticsTrackerImpl, dan kita memerlukan instance klien jaringan, yang diketahui cara penyediaannya oleh grafik.
Jadi, di balik layar, plugin compiler menghasilkan kode yang terlihat seperti ini.
Jadi, jika Anda memiliki AnalyticsTracker, pengambil akan membuat instance klien jaringan dan meneruskannya ke konstruktor AnalyticsTrackerImpl, yang merupakan hal yang baik.
Namun, dengan pelacakan yang diaktifkan, kini Anda dapat melihat biaya pembuatan tidak hanya tracker impl, tetapi juga setiap dependensi yang diperlukan.
Jadi sekarang, kami memungkinkan Anda untuk melihat tidak hanya biaya pembuatan instance jenis, tetapi juga semua dependensinya dalam rekaman aktivitas, dan itu sangat efektif.
Jadi, dengan menggunakan informasi ini, Wise, yang merupakan aplikasi keuangan, meningkatkan startup aplikasinya sebesar 45%.
Mereka dapat menunda hal-hal yang tidak perlu diinisialisasi selama startup aplikasi, dan mereka juga mengidentifikasi beberapa item dengan cakupan yang salah, di mana hal-hal yang seharusnya menjadi singleton ternyata tidak sengaja bukan singleton, dan ini adalah hal-hal yang dapat Anda lihat dan perbaiki dengan mudah dalam kode Anda.
Jika Anda melihat metrik startup mereka, hasilnya sangat mengesankan.
Mereka tidak hanya meningkatkan waktu ke frame awal, tetapi juga meningkatkan waktu ke tampilan penuh.
Partner lain, BandLab, menggunakan informasi yang sama tentang CI.
Jadi, Anda tidak hanya mengetahui biaya setiap binding @Inject, tetapi juga mengetahui thread mana yang menimbulkan biaya tersebut.
Jadi, setelah mengetahuinya, Anda dapat menemukan semua binding @Inject yang mahal di thread utama dan di CI, Anda dapat menjalankan kueri untuk mengatakan, hei, beri saya daftar semua binding yang mahal, lalu kaitkan kembali ke perubahan yang memperkenalkannya, dan kemudian Anda dapat menyalahkan perubahan yang sebenarnya dan mencoba memperbaikinya.
Rahul Ravikumar
Oke.
Sejauh ini, saya telah membahas semua hal yang telah kami tingkatkan dibandingkan dengan Tracing 1, tetapi sekarang saya akan membahas fitur baru yang ada di Tracing 2 yang sebelumnya tidak pernah ada.
Jadi, salah satu fitur intinya disebut Penyebaran Konteks dan karena aplikasi modern makin kompleks, workload berjalan di beberapa thread, beberapa coroutine, dan beberapa proses.
Anda ingin dapat memvisualisasikan cara permintaan disebarkan antara setiap thread versus proses.
Dan itulah yang dimungkinkan oleh Penyebaran Konteks.
Jadi, jika saya hanya memberi Anda daftar irisan dan tanpa memberi tahu Anda apa pun tentang apa yang menyebabkan apa, irisan tersebut berguna, tetapi tidak terlalu mudah untuk dipahami.
Namun, jika kami memberi tahu Anda bahwa ini adalah rantai peristiwa kausal yang terjadi, Anda akan jauh lebih mudah mengetahui apa yang terjadi, lalu mengaitkan biaya setiap bagian.
Inilah yang disediakan oleh Penyebaran Konteks.
Anda akan senang mengetahui bahwa Penyebaran Konteks didukung sepenuhnya, jadi berikut adalah contoh nyata.
Melihat kembali rekaman aktivitas Perfetto com.example.app, misalnya performInitialize memerlukan waktu terlalu lama dan Anda ingin menunda biaya atau memindahkannya ke thread lain.
Sesuatu yang benar-benar dapat Anda lakukan.
Jadi, misalnya saya memindahkan performInitialize ke rangkaian pesan lain.
Sekarang, Anda telah kehilangan sifat hierarkis slice tersebut.
Jadi, sekarang Anda tidak dapat lagi mengetahui bahwa initializeComponent adalah hal yang menyebabkan performInitialize terjadi, kecuali jika Anda melihat kodenya.
Idealnya, Anda ingin panah memberi tahu bahwa A menyebabkan B, lalu Anda dapat menyimpulkan rantai peristiwa kausal.
Anda mungkin pernah melihat pelacakan sistem yang menunjukkan bahwa kami benar-benar melakukan hal ini untuk transaksi binder di platform.
Jadi, di sini Anda dapat melihat bahwa benchmark Compose melakukan transaksi binder ke system_server untuk menyiapkan frame.
Jadi, ini adalah hal yang selalu memungkinkan dari perspektif pelacakan platform, tetapi kami belum pernah menyediakan alat ini untuk developer aplikasi.
Jadi, sekarang Penyebaran Konteks coroutine Kotlin didukung sepenuhnya di Tracing 2.0.
Anda tidak perlu melakukan apa pun.
Anda hanya perlu mengeluarkannya dari kotak.
Jadi, di sini kita memiliki satu metode penangguhan yang disebut fetchProfile.
Metode ini memanggil client.get, yang merupakan metode penangguhan lain, lalu beralih ke Dispatchers.Default untuk melakukan deserialisasi respons.
Kode coroutine yang sangat umum, sesuatu yang mungkin Anda tangani setiap hari.
Sekarang, katakanlah kita ingin melacaknya.
Kita menambahkan bagian rekaman aktivitas.
Jadi di sini, alih-alih trace, kita akan menggunakan traceCoroutine API karena ini adalah blok kode penangguhan, lalu untuk panggilan dalam sebelum kita beralih konteks ke Dispatchers.Default, kita akan menambahkan bagian trace dalam lainnya menggunakan traceCoroutine API yang sama.
Sekarang, dalam trace, Anda akan melihat sesuatu seperti ini.
Anda akan melihat bahwa pekerjaan kita dimulai di worker-1, lalu beralih konteks dan berpindah ke worker-3. Anda akan melihat panah yang membantu dalam rekaman aktivitas yang menunjukkan hal tersebut.
Tidak hanya itu, jika Anda memperbesar kotak di tengah, Anda dapat melihat bahwa deserialize sebenarnya dimulai di worker-1 dan panggilan ke withContext adalah penyebab terjadinya pengalihan konteks, lalu dilanjutkan ke worker-3, dan kemudian, fetchProfile dilanjutkan di worker-3 karena mesin coroutine ingin meminimalkan jumlah pengalihan konteks yang terjadi.
Anda dapat melihat dengan tepat kapan coroutine ditangguhkan, kapan dilanjutkan, dan Anda dapat melihat rantai peristiwa kausal lengkap.
Hal lain yang dapat dilakukan Tracing 2 adalah kemampuan untuk menambahkan metadata kustom ke trace.
Jadi, sebelumnya, satu-satunya alat yang Anda miliki adalah nama bagian rekaman aktivitas, tetapi sekarang, Anda dapat menambahkan blok metadata yang memungkinkan Anda menambahkan entri metadata sebanyak yang Anda inginkan.
Dan Anda dapat menambahkannya ke trace.
Saat melihat rekaman aktivitas yang sebenarnya, di sini Anda dapat melihat bahwa semua metadata yang Anda tambahkan sebenarnya ada dalam rekaman aktivitas untuk digunakan dan dipakai oleh semua alat.
Jadi sekarang, Anda dapat menyematkan semua yang Anda ketahui, semua informasi tambahan yang selalu ingin Anda sertakan.
Jadi, kami telah memberikan banyak fitur abstrak yang dapat diaktifkan oleh pelacakan, tetapi semua ini akan terlihat jelas dalam fitur baru di Jetpack Compose yang disebut Pelacakan Rekomposisi.
Fitur ini disertakan sebagai bagian dari Compose 1.13, sehingga siap digunakan sekarang.
Berikut contohnya.
Ini adalah Pelacakan Komposisi yang mungkin sudah Anda kenal.
Hal ini telah ada sejak awal Compose.
Ini memberi tahu Anda biaya relatif composable dan semua, Anda tahu, subbagiannya, serta biaya masing-masing pada thread tempatnya terjadi.
Jadi, ini cukup mudah.
Namun, data ini tidak memberi tahu Anda konteksnya.
Metrik ini tidak memberi tahu Anda alasan hal ini terjadi.
Alat ini tidak memberi tahu Anda alasan terjadinya rekomposisi.
Jadi, jika saya memperkecil tampilan, itulah region yang diminati yang baru saja kita lihat di slide sebelumnya.
Dan di sebelah kiri, Anda dapat melihat bahwa ada peristiwa input pengiriman yang terjadi.
Mungkin itulah yang mengubah beberapa status, dan mungkin itulah yang menyebabkan rekomposisi.
Namun, hal ini tidak jelas.
Anda tidak tahu pasti.
Namun, dengan pelacakan rekomposisi, kini kami menambahkan metadata kustom ke dalam pelacakan yang memberi tahu Anda alasan pasti terjadinya rekomposisi.
Tidak hanya itu, jadi sekarang sangat mudah bagi Anda untuk mengetahui bahwa peristiwa ini terkait.
Kemudian, jika Anda mengkliknya, Anda akan diberi tahu status apa yang berubah.
Ini akan memberi tahu Anda bahwa itu adalah status, itu adalah nilai status yang dapat diubah yang dialihkan ke salah, yang sebelumnya benar.
Tidak hanya itu, kami bahkan akan memberi tahu Anda stack panggilan persis yang menyebabkannya.
Jadi, di sini Anda dapat melihat bahwa, AbstractClickableNode.performClick terjadi, yang menyebabkan status yang dapat diubah berubah, yang menyebabkan rekomposisi terjadi.
Jadi, ini sangat keren, sesuatu yang belum pernah bisa kita lakukan sebelumnya.
Alat ini juga tersedia, maaf, semua fungsi ini juga tersedia di alat Android Performance Analyzer yang baru, jika Anda ingin mencoba beberapa alat agen.
Dan benar.
Jadi, kami telah memberi tahu Anda bahwa propagasi konteks didukung sepenuhnya untuk coroutine Kotlin.
Namun, bagaimana dengan kode yang menggunakan campuran kode coroutine dan non-coroutine, atau mungkin Anda menjalankan thread sendiri, atau mungkin Anda memiliki beberapa kode brownfield yang terlalu lama yang menggunakan callback karena alasan tertentu?
Oke.
Jadi, kabar baiknya adalah Anda masih bisa mendapatkan semua, Anda tahu, kebaikan propagasi konteks di sana.
Jadi, misalnya kita memiliki, Anda tahu, API brownfield yang menggunakan callback dan eksekutor.
Implementasi ini menggunakan executor.execute, memanggil runCatching, yang merupakan detail implementasi, mendapatkan respons, lalu memberi tahu callback tentang respons tersebut.
Oke.
Sekarang, jika saya ingin melacaknya, saya akan melakukan Tracer.global.trace, memberinya label, lalu mengelilingi blok.
Namun, karena saya juga ingin mempertahankan rantai peristiwa kausal, saya akan menerima jenis baru yang opsional, yang disebut token propagasi.
Saya akan meneruskan token ke API pelacakan internal.
Jadi, siapa pun yang memanggil metode ini dapat secara opsional memberi saya token propagasi, sehingga saya dapat mempertahankan rantai kausal peristiwa yang terjadi.
Oke.
Sekarang, pemanggil API tersebut dapat berupa API penangguhan.
Jadi, di sini saya memiliki suspend fun profileRequest, yang sekarang akan memanggil API yang menggunakan callback dan eksekutor.
Di sini, karena saya menjembatani dua dunia, yaitu dunia penangguhan dengan dunia callback, saya akan menggunakan builder suspendCoroutine.
Saya akan mendapatkan kelanjutan, lalu saya akan memanggil API, dan kemudian melanjutkan kelanjutan dalam callback, setelah saya mendapatkan respons.
Lalu, berikut adalah eksekutor yang saya tentukan, yang disebut profileRequestContext.
Ini adalah eksekutor thread tunggal.
Dan karena traceCoroutine menyematkan token propagasi di dalam konteks coroutine, saya dapat memperoleh token propagasi dari dalam konteks coroutine, lalu meneruskannya sebagai input ke API brownfield, sehingga saya masih dapat mempertahankan rantai peristiwa kausal.
Dan dalam rekaman aktivitas, hal ini terlihat sangat jelas.
Jadi, di sini Anda memiliki sesuatu yang dimulai di worker-3 yang beralih ke eksekutor thread tunggal, setelah kita melakukan pengalihan konteks, lalu dilanjutkan kembali di worker.
Jadi, ini cukup rapi.
Rahul Ravikumar
Oke.
Hal lain yang dapat Anda lakukan adalah menyesuaikan Tracer.global.
Sejauh ini, Tracing 2.0 API memberi Anda setelan default yang sangat baik untuk Tracer.global, tetapi jika Anda ingin menyesuaikannya, Anda dapat melakukannya.
Selain itu, Tracing 2.0 mendukung JVM dan Android karena kami ingin pelacakan didukung sepenuhnya untuk library Java dan Android.
Jadi, tiga langkah untuk inisialisasi adalah, Anda membuat sink trace.
Sink trace secara efektif adalah cara paket trace disimpan.
Konfigurasi ini menentukan format kabel dan lokasi trace output tempat trace tersebut disimpan.
Kami memberi Anda implementasi siap pakai untuk sink rekaman aktivitas yang mendukung format Perfetto, tetapi Anda tentu saja dapat menulis sink rekaman aktivitas Anda sendiri.
Hal ini kembali ke upaya untuk menyelesaikan masalah bahwa atrace adalah satu-satunya backend yang tersedia di Tracing 1.
Kami ingin memperbaikinya.
Jadi, sekarang, jika Anda ingin menulis sink OpenTelemetry atau ingin membawa sink Anda sendiri, hal itu sangat mungkin dilakukan.
Anda dapat memilih untuk menggantinya.
Setelah memiliki sink, Anda dapat membuat driver trace, dan memberinya sink.
Lalu, Anda juga dapat memilih kategori yang ingin diaktifkan.
Jadi, ini adalah bagian yang sangat penting dari kategori.
Jadi, Anda dapat memutuskan bahwa dalam rilis, beberapa kategori lebih penting daripada yang lain, jika dibandingkan dengan debug, dan Anda dapat mengatakan bahwa kategori tersebut adalah kategori yang ingin Anda aktifkan.
Atau, Anda juga dapat mengatakan, "Saya ingin mengaktifkan semua kategori, dari mana pun asalnya".
Dan itu tidak masalah.
Anda juga dapat menambahkan atribut kustom yang bersifat global ke trace Anda.
Jadi, Anda dapat menyematkan hal-hal seperti versi build, ragam, atau metadata lain yang ingin Anda lampirkan ke trace menggunakan addAttribute API.
Terakhir, Anda dapat mendaftarkan tracer dengan memanggil setGlobalTracer.
Hal ini mengikat Tracer.global ke instance tracer ini, dan selanjutnya, hal ini tersedia untuk proses tersebut.
Di Android, karena proses memiliki siklus proses yang jauh lebih jelas, Anda hanya perlu mengimplementasikan AbstractTraceDriver.Factory, mengganti metode create-nya, dan melakukan hal yang sama seperti sebelumnya.
Jadi, Anda membuat sink, lalu membuat driver.
Anda tidak perlu mendaftar di sini.
Kami akan melakukan pendaftaran untuk Anda, karena kami tahu bahwa inilah yang terjadi terlebih dahulu.
Oke.
Baiklah, kami ingin menegaskan kembali bahwa pelacakan siap digunakan di berbagai platform.
Ini adalah pilihan yang sangat disengaja karena kami tahu Compose berjalan di beberapa platform, dan kami ingin memungkinkan Anda melakukan pelacakan di sebanyak mungkin tempat.
Saat ini, kami mendukung Android dan JVM, tetapi implementasi kami memungkinkan kami untuk mendukung platform mendatang jika kami mau.
Rahul Ravikumar
Anda akan senang mengetahui bahwa R8, yang merupakan alat yang digunakan untuk menyingkat dan mengoptimalkan kode sumber di Android, menggunakan Tracing 2.0.
Dengan memanfaatkan trace, kami telah mengoptimalkan R8 untuk menyingkat dan mengoptimalkan kode Anda 25% lebih cepat.
Artinya, waktu build lebih singkat dan waktu tunggu untuk proses pengoptimalan juga lebih singkat.
Kami tidak akan membahas setiap pengoptimalan yang kami lakukan di R8, tetapi kami hanya ingin membahas satu pengoptimalan, hanya untuk memberi Anda gambaran tentang apa yang dapat dilakukan pelacakan.
Jadi, pada intinya, R8 adalah transformator source-to-source.
Jadi, Anda mendapatkan banyak JAR, lalu menyusutkan dan mengoptimalkannya, dan menghasilkan kumpulan JAR lain yang dapat Anda dex.
Jadi di sini, AGP memulai dengan membaca JAR, yang tidak hanya mencakup aplikasi Anda, tetapi juga semua dependensinya.
Jadi, alat ini menggunakan worker Gradle untuk mulai membaca semua JAR input.
Anda memiliki banyak sekali JAR yang ingin dibaca.
Kemudian, setelah Anda selesai membaca JAR, R8 mulai mengurai kode, dan membangun model dari apa yang diwakili oleh kode Anda, dan semua titik entrinya, sehingga dapat mulai mengoptimalkan dan menyingkat kode Anda.
Nah, itulah slice, await, yang menunjukkan kapan R8 benar-benar siap untuk memulai proses pengoptimalan, bukan?
Anda mungkin melihat beberapa ruang kosong di tengah, dan Anda mungkin bertanya-tanya mengapa ada, Anda tahu, waktu CPU yang tidak digunakan.
Alasannya adalah karena cara kerja API lama adalah menunggu semua worker membaca semua file terlebih dahulu sebelum mengurai apa pun.
Tentu saja, kita dapat memperbaikinya, dan itulah yang kami lakukan.
Jadi, di AGP 9, Anda dapat melihat bahwa begitu selesai membaca JAR input, kami langsung mulai memprosesnya.
Dan kita tidak perlu menunggu setiap worker selesai membaca inputnya.
Hal ini membuat jumlah waktu yang kita tunggu untuk membaca semua input berkurang banyak.
Jadi, ini adalah pengoptimalan yang jelas dan dapat Anda lihat dengan sangat jelas saat melihat rekaman aktivitas, tetapi tidak begitu jelas saat Anda hanya melihat kode sumber untuk melihat apa yang layak dioptimalkan.
Alat lain yang kami gunakan setiap hari sebagai engineer AndroidX adalah Metalava.
Metalava adalah alat yang kami gunakan untuk memastikan bahwa API apa pun yang kami kirimkan memiliki jaminan kompatibilitas API yang Anda harapkan, dan dapat digunakan sepenuhnya oleh orang eksternal tanpa ada kesalahan yang ingin kami hindari.
Ini adalah alat yang berjalan di setiap API publik dan API yang dibatasi, jadi setiap kali kita menghemat waktu di sini, sebenarnya kita mendapatkan kembali waktu sebagai engineer AndroidX.
Metalava juga menggunakan pelacakan untuk meningkatkan waktu pasca-pengiriman sebesar 15%.
Dan masuk ke pelacakan untuk menjelaskan apa yang terjadi, jadi Metalava menjalankan dua jenis pemeriksaan: yang pertama adalah memeriksa API yang dibatasi, dan yang kedua adalah memeriksa API publik.
Namun, Anda mungkin melihat sebuah pola.
Kita melakukan banyak penyiapan untuk menjalankan pemeriksaan tersebut dua kali.
Jadi, yang terjadi adalah semua input program dibaca, kami membangun PSI, yang merupakan antarmuka struktur program, atau, Anda tahu, persis seperti apa bentuk kode Anda yang dapat dinalar.
Kemudian, kita membangun AST sebelum mulai menerapkan semua pemeriksaan lint yang diinginkan.
Dan kita melakukan pekerjaan yang mahal ini dua kali.
Bagaimana cara kami memperbaikinya?
Kami baru melakukannya sekali.
Jadi, daripada melakukan semua pekerjaan penyiapan itu dua kali, kita hanya melakukannya sekali, dan kita menggunakan kembali input tersebut untuk pemeriksaan terbatas dan pemeriksaan publik, sehingga mendapatkan semua penghematan tersebut.
Ya.
Oke.
Rahul Ravikumar
Jadi, setelah saya memberi Anda gambaran tentang apa yang dapat dilakukan Tracing 2.0, penting untuk diketahui bahwa meskipun pelacakan itu penting, mengetahui apa yang harus dilacak juga sama pentingnya.
Anda tidak ingin menyebarkan rekaman aktivitas di mana-mana.
Anda harus sangat berhati-hati dalam memilih, dan saya akan mencoba memberikan beberapa panduan tentang apa yang layak dilacak.
Jadi, hal pertama yang harus Anda lakukan adalah menemukan celah yang tidak dapat dijelaskan dalam rekaman aktivitas Anda.
Jadi, kapan pun Anda melakukan hal ini saat thread berada dalam status berjalan atau runnable, dan Anda melihat celah yang jelas dalam pelacakan sistem, dan Anda tidak dapat memahaminya, serta Anda tidak tahu apa yang dilakukan aplikasi, hal itu mungkin perlu diselidiki.
Pada tahap tersebut, saya mungkin akan mengambil pelacakan metode yang dilapisi dengan pelacakan sistem, dan melihat apa yang layak dilacak, lalu saya mungkin akan menambahkan bagian pelacakan yang relevan tersebut.
Anda juga ingin memprioritaskan melalui perjalanan pengguna.
Jadi, Anda ingin melihat startup aplikasi.
Anda ingin melihat perjalanan pengguna aplikasi inti, dan ingin mengetahui apakah Anda dapat menjelaskannya dengan melihat trace.
Jadi, setiap kali Anda tidak dapat memahami sesuatu, hal itu layak untuk dilacak.
Anda juga harus melihat stack panggilan yang dalam atau penggunaan CPU yang tidak dapat dijelaskan dari trace dan mencoba mencari tahu apa yang sebenarnya terjadi, lalu mengonversi bagian codebase tersebut menjadi trace.
Jadi, Anda dapat melacaknya.
Kemudian, setiap kali thread Anda tidur, Anda harus memastikan bahwa Anda dapat memahami alasan thread tersebut tidur.
Thread tersebut seharusnya menunggu I/O, atau menunggu transaksi binder, atau menunggu beberapa peristiwa input eksternal yang Anda harapkan terjadi.
Namun, jika Anda mengalami, Anda tahu, tidur yang tidak dapat dijelaskan, hal itu sangat layak untuk diselidiki karena jelas mungkin ada sesuatu yang mengintai di sana.
Kemudian, setelah Anda menyisipkan semua bagian rekaman aktivitas dalam kode tersebut, Anda harus mengonversinya menjadi benchmark agar dapat melacak perubahannya.
Jadi, seiring berkembangnya code base, Anda dapat melihat apakah metrik berubah, apakah dasbor Anda benar-benar mencerminkan perubahan besar, karena dengan begitu Anda tahu bahwa ada sesuatu yang penting yang berubah.
Atau, Anda dapat melewati semua langkah sebelumnya dan meminta agen Anda melakukannya.
Ambil, Anda tahu, pedoman ini, jadikan sebagai keterampilan, lalu arahkan agen favorit Anda ke sana, dan biarkan agen tersebut mencobanya.
Ya.
Rahul Ravikumar
Jika Anda yakin bahwa pelacakan adalah upaya yang bermanfaat dan Anda harus melakukannya, berikut adalah penyiapan project-nya.
Ini cukup mudah.
Tracing hanyalah library Java tradisional yang sederhana, jadi Anda menentukan dependensi pada androidx.tracing:tracing-wire, yang merupakan kombinasi pelacakan plus driver pelacakan yang kompatibel dengan Perfetto, dan versi stabil saat ini adalah 2.0.5.
Jika Anda adalah library Java, hal ini sama persis; sekali lagi, ini adalah API multiplatform sepenuhnya.
Kami ingin memperluasnya ke platform lain jika memungkinkan.
Dan ya, saya hanya ingin memberikan ringkasan singkat.
Jadi, saya telah membahas semua fitur baru yang keren yang kami tambahkan.
Jadi, Penyebaran Konteks sangatlah efektif.
Kita dapat menyematkan informasi kustom, metadata, informasi stack panggilan, dan berbagai hal lainnya.
Saya belum membahas banyak hal.
Anda tentu saja dapat mengubah format pelacakan, mengubah sink pelacakan, dan, Anda tahu, membawa data pelacakan ke OpenTelemetry.
Semua itu adalah hal yang dapat Anda lakukan.
Pelacakan bersifat multiplatform.
Sekali lagi, ini adalah keputusan yang sangat, sangat disengaja karena kami ingin sebanyak mungkin orang dapat memanfaatkannya.
Dan semua alat yang kami sediakan, baik itu Perfetto, Benchmark AndroidX, penganalisis performa baru, atau Android Profiler lama, semuanya mendukung Tracing 2.0.
Demikian dari saya, terima kasih atas perhatiannya.
Semoga Anda menikmati Dev Summit ini, dan terima kasih.