Araçlar ve Performans

Trace me if you can: Automated instrumentation and field profiling

Hoparlörler

  • Rahul Ravikumar

    Staff Software Engineer

Hakkında

Konuşma hakkında

Android uygulamalarını optimize etmek için eşzamanlı iş akışları ve eş yordam askıya alma işlemleri hakkında ayrıntılı bilgi edinmek gerekir.

Yerel profil oluşturma, faydalı bir anlık görüntü sunsa da bu analizleri ek yük olmadan üretime ölçeklendirmek hâlâ zor bir iştir.

Bu oturumda, sürekli performans geri bildirim döngüsü için mimari bir plan sunulmaktadır.

androidx.tracing 2.0: Arka uçları dinamik olarak değiştirin ve eş yordam bağlamlarını (Perfetto akışları) iş parçacıkları arasında yayın.

Akıllı Araçlar: Yoğun noktaları bulmak için yerel ART izlemeyi kullanın, ardından düşük ek yük içeren izleme noktalarının eklenmesini otomatikleştirin.

Makro karşılaştırma: CI'daki fiziksel cihazlarda gerilemeleri takip edin ve performans artışlarını doğrulayın.

Saha İzleme: ProfilingManager ile yerel ve CI izlemenin ötesine geçin.

Özet

  • Tracing 2.0, etiket uzunluğu sınırlarını kaldırmak ve yedi kat daha hızlı çalışmak için eski Android izleme API'lerinin yerini alır. Ayrıca OpenTelemetry gibi arka uçlar için özel havuzlar oluşturmanıza da olanak tanır.
  • Bağlam yayma, iş parçacıkları, eş yordamlar ve süreçler arasındaki nedensel ilişkileri eşler. Eşzamansız yürütmeyi traceCoroutine ile izleyebilir veya yayılma jetonlarını geri çağırma tabanlı koda iletebilirsiniz.
  • Jetpack Compose 1.13, yeniden oluşturma işlemlerinin neden gerçekleştiğini göstermek için özel meta verileri kullanan yeniden oluşturma izleme özelliğini ekler. İzler, değiştirilen durum değerlerini ve bunları tetikleyen tam çağrı yığınlarını kaydeder.
  • Android derleme araçları, darboğazları tespit etmek ve derlemeleri hızlandırmak için Tracing 2.0'ı kullanır. R8 kod daraltma işlemini %25 daha hızlı hale getiren ve Metalava gönderim sonrası sürelerini %15 azaltan izleme destekli optimizasyonlar.

Gemini Notebook

Konular

  • izleme
  • android-performance
  • perfetto
  • bağlam yayma
  • jetpack-compose
  • eş yordamlar
  • profil çıkarma

Transkript

Android izlemeye giriş ve izlemenin gelişimi

  • Rahul Ravikumar

    Herkese merhaba.

  • Adım Rahul.

  • Android Geliştirici Deneyimi ekibinde mühendis olarak çalışıyorum.

  • Uygulama ve kitaplık performansına odaklanıyorum. Bu konuşmada izleme konusunu ele alacağım.

  • İzleme konusunu ayrıntılı olarak ele almadan önce, konuyu takip edebilmeniz için bazı ortak terimleri açıklamak istiyorum.

  • Bu konuşmada izleme dediğimde, açık izlemeden, uygulamanın ne yaptığını bilmeniz için kodu manuel olarak izlemeden bahsediyorum.

  • Daha sonra bahsedeceğim otomatik profil oluşturuculardan bahsetmiyorum.

  • Manuel izleme, kod tabanınızda iz bırakma sanatıdır. Böylece daha sonra bir performans sorunu veya başka bir sorunla karşılaştığınızda bu izleri takip edebilirsiniz.

  • Genellikle günlüklerden çok daha iyidir.

  • Büyük bir uygulamanın Logcat çıktısını gördünüz mü bilmiyorum.

  • Genellikle kolayca anlayamayacağınız devasa bir metin duvarıdır.

  • İzleme ise çok daha iyidir.

  • Görselleştirmesi daha kolaydır.

  • Süreleriniz var.

  • Biraz yapınız var.

  • Elinizde bazı araçlar var. Bu sayede verileri farklı açılardan inceleyebilir ve tam olarak ne zaman ne olduğunu görebilirsiniz.

  • Bu nedenle çok daha iyi.

  • Temsilcilerinize bir izi gösterip soru sormalarını isteyebilirsiniz.

  • Trace Processor ve karşılaştırmalar gibi araçları kullanabilir, hatta izlerinizi metriklere dönüştürebilirsiniz.

  • Bunlar, izlerle yapabileceğiniz ancak Logcat ile yapılması zor olan işlemlerdir.

  • Profil oluşturma ise (otomatik profil oluşturmadan bahsediyorum) genellikle bildiğiniz bir soruna yanıt olarak yapılır.

  • Örneğin, uygulamanızın yavaş başladığını veya bir şeylerin aksadığını fark etmiş olabilirsiniz. Bu sorunu daraltmak ve neler olduğunu anlamak istiyorsunuz.

  • Bu noktada, size yardımcı olacak manuel izleriniz yoksa otomatik profil oluşturma devreye girer.

  • Her bir yöntem girişini ve çıkışını izlediğiniz ART yöntem izleme gibi bir yöntem kullanabilirsiniz.

  • Alternatif olarak, Simpleperf gibi araçlarla yığın örneklemeye bakıyor olabilirsiniz.

  • Bu nedenle, her bir yöntem giriş ve çıkışını kullanıp yüksek bir ek yük oluşturmak yerine çağrı yığını örneklerine bakarak uygulamanızın etkin yolunda ne olduğunu görürsünüz.

  • 2026 yılındayız ve RAM her yerde sorun olmaya devam ediyor. Bu nedenle bellek, bellek sızıntıları ve öbek profillerine bakıyor olabilirsiniz.

  • Bu da yararlanabileceğiniz başka bir profil oluşturucudur.

  • Yığın tutma yollarına bakabilirsiniz.

  • Hangi kodun bellek ayırdığını görebilirsiniz. Bu araçla yapabileceğiniz analizler bunlardır.

  • Doğru.

  • Artık bu kelime dağarcığına sahibiz.

  • Şimdi neden yeni bir kitaplık oluşturduğumuzdan bahsedelim.

  • İzleme API'leri olan 1.0 API'leri ilk olarak Android Jelly Bean'de kullanıma sunulmuştu.

  • Bu, 2012'deydi.

  • Bu, 14 yıldan daha uzun bir süre önceydi.

  • O zamandan beri API'ler sandığınız kadar gelişmedi.

  • Birkaç uzantı ekledik.

  • Asenkron etkinlikler ve sayaçlar Android 10'da eklenmiştir.

  • Bu, 2019'daydı.

  • Hepsi bu kadardı.

  • API o zamandan beri değişmedi.

  • Ancak ekosistemde büyük değişiklikler oldu.

  • Platform izleme özelliği çok büyük bir gelişme kaydetti ancak bu gelişme, API eklemeleri açısından size yansımadı.

  • Bu, değiştirmek istediğimiz bir durum.

  • Diğer büyük sorun ise izlemenin 1.0'da sabit bir izleme arka ucuna sahip olmasıdır. Yani kodunuza bir izleme bölümü eklediğinizde bu bölüm her zaman sistem izleme arabelleğine eklenir.

  • Atrace, bu verilere sahip olan Android izleme alt sistemidir.

  • Yani izlerinizi alıp alan telemetrisine dönüştürmek istiyorsanız bu gerçekten çok zor. Çünkü öncelikle atrace'in bu verileri nasıl depoladığını anlamanız gerekir.

  • Bu, iyi belgelenmiş ancak tüketilmesi zor olabilecek bir biçimdir.

  • Bu, düzeltmek istediğimiz bir durum.

  • Bu nedenle, izleme verilerinizi istediğiniz yere taşıyabileceğiniz araçlar sunmak istiyoruz.

  • Ayrıca, Tracing 1.0'da etiketlerin 128 karakterle sınırlandırıldığı bir kısıtlama da vardı.

  • 2012'de bu kısıtlama makul görünmüş olabilir ancak 2026'da oldukça tuhaf görünüyor.

  • Daha da kötüsü, izinize ek meta veri ekleyemezsiniz. Bu da başka bir sorundur.

  • Bir de ek yük var.

  • Bu nedenle, uygulamanızı izlerken ek yük konusunda son derece dikkatli olmanız gerekir. Çünkü bir sistemi gözlemleme eylemi, sistemin arka planda yaptığı işleri değiştirmemelidir.

  • Yeniden oluşturmak istediğiniz bir yarışma durumu varsa izleme, yarışma durumunu ortadan kaldırmamalıdır.

  • Bu nedenle, diğer durumlarda yaptığınız tüm semantik işlemleri koruduğunuzdan emin olmanız gerekir.

  • Tracing 1.0'ın ek yükü nispeten yüksekti ve bunu iyileştirmek istedik.

  • Anladım.

  • Sorunlardan çok bahsettim.

  • Şimdi, bu sorunlardan bazılarını görsel olarak inceleyelim ve uygulamada nasıl birleştiklerini görelim.

  • Burada bir Perfetto izi var.

  • com.example.app adlı bir uygulama için.

  • Bir ana iş parçacığımız ve initializeComponent adlı tek bir dilimimiz var.

  • Şimdi, ideal olarak, biraz daha ayrıntı istiyoruz.

  • Şimdi bir ayrıntı ekleyelim.

  • Artık initializeComponent'in performInitialize'i çağırdığını biliyoruz.

  • Hangi bileşenin başlatıldığını hâlâ bilmiyoruz.

  • Şu anda araç setimizde İzleme 1'e sahip tek araç ad olduğu için bunu dilimin adına ekliyoruz.

  • İzleme dilimi adlarının 128 karakterle sınırlı olduğunu ve izlemenizde kısaltıldığını unutmayın.

  • Şimdi, bir de üstüne üstlük, kesme işleminin ek yükü de izleme yaparken karşılaştığınız ek yük haline geldi.

  • Bu sorunla çok hızlı bir şekilde karşılaşırsınız.

  • Bu, gerçekten düzeltmek istediğimiz bir sorundu.

  • Perfetto izini ve görsel olarak nasıl göründüğünü gördünüz.

  • Şimdi bu izleme bölümlerini oluşturacak kodu yazma açısından bakalım.

  • Yine initializeComponent API'sini kullanıyoruz.

  • Bir bağlam ve ad alır, performInitialize yöntemini çağırır.

  • Şu ana kadar her şey yolunda.

  • Şimdi Tracing 1.0 API ile bir iz eklemek istiyoruz. Bunun için androidx.tracing.trace öğesini içe aktarır ve bir izleme bloğu kullanırsınız.

  • Satır öğesinin adını yazın.

  • Burada performInitialize.

  • Ancak daha önce yapmak istediğimiz gibi, bileşenin adını bilmek istiyoruz. Bu nedenle Kotlin'in dize interpolasyonunu kullanıp adı ekleyeceğiz.

  • İlk sorun da burada ortaya çıkıyor.

  • Burada 128 karakter sınırlamamız var.

İzleme 2.0 ve performansa genel bakış

  • Rahul Ravikumar

    Bu sorunu Tracing 2 ile çözebiliriz.

  • androidx.tracing.trace yerine Tracer kullanırsınız.

  • API, oldukça benzer görünüyor.

  • trace yerine Tracer.global.trace var.

  • Bir kategoriniz var.

  • Kategoriler hakkında daha sonra ayrıntılı olarak konuşacağız ancak temel olarak bir adınız var.

  • Ardından, izlemeye çalıştığınız kod bloğu gelir.

  • Artık 128 karakterlik sınırlama da yok.

  • İzleme ek yükünden bahsetmiştim.

  • Bu konuyu biraz daha ayrıntılı olarak ele almak ve bu konuda nasıl iyileştirmeler yaptığımızı görmek istiyorum.

  • Android 16 yüklü bir Pixel 6a'da tek bir başlangıç ve bitiş bölümü ekleme işlemi yaklaşık 1.200 nanosaniye sürdü.

  • Bu süre çok uzun görünmeyebilir ancak çok sayıda izleme bölümü ekleyen yoğun bir kodunuz varsa uygulamanızın kareleri oluşturmak için harcayabileceği zamanı boşa harcamış olursunuz.

  • Bu nedenle, zamanınızı almak istemiyoruz.

  • AndroidX Perfetto SDK ile bu konuda önemli iyileştirmeler yaptık.

  • Bu, Oluşturma İzleme için kullanıma sunduğumuz deneysel bir SDK'ydı ve aslında durumu çok daha iyi hale getirdi.

  • Bu, JNI bağlamaları olan Perfetto C SDK'sı olduğundan ve C SDK'sı APK'nızda yaklaşık 4 MB yer kapladığından bunu göndermenizi istemiyoruz.

  • Bu, göndermenizi istediğimiz bir şey değil.

  • Tracing 2 ile artık özel olarak tasarlanmış bir kitaplığımız var.

  • Genel giderleri çok daha fazla iyileştirdik ve artık Tracing 2'nin 7 kat daha hızlı olduğunu bilmekten memnuniyet duyacaksınız. Bu da yapmak istediğiniz şeyleri yapmak için daha fazla zamanınız olduğu ve altyapının daha az zaman aldığı anlamına geliyor.

  • Bu tür bir gelişme, daha önce mümkün olmayan neleri mümkün kılıyor?

  • Örneğin, Metro'nun çalışma zamanı izleme özelliği bunlardan biridir.

  • Metro, bilmeyenler için bir bağımlılık ekleme kitaplığıdır.

  • Kotlin Multiplatform'u destekler.

  • Kotlin derleyici eklentisi kullanır.

  • Bağımlılık ekleme için tüm kodu oluşturur ve kodunuzdaki her bir @Inject maliyetini görselleştirmeyi kolaylaştırmak için Tracing 2.0 ile entegre olur.

  • Örneğin,

  • Bir uygulama grafiğimiz olduğunu varsayalım.

  • Metro'da her şey bir grafiğe göre kapsamlandırılır. Bu nedenle tek bir alanımız (AnalyticsTracker) vardır.

  • Ayrıca bir "provides" bağlamamız da var.

  • OkHttpClient'yi impl olarak kullanan bir ağ istemcimiz var. AnalyticsTracker'in uygulaması AnalyticsTrackerImpl'den geliyor ve ağ istemcisinin bir örneğine ihtiyacımız var. Graf, bu örneği nasıl sağlayacağını biliyor.

  • Yani arka planda derleyici eklentisi buna benzer bir kod oluşturur.

  • Dolayısıyla, AnalyticsTracker varsa alıcı, ağ istemcisinin bir örneğini oluşturur ve bunu AnalyticsTrackerImpl oluşturucusuna iletir. Bu iyi bir şeydir.

  • Ancak artık izleme etkinleştirildiğinde, yalnızca izleyici uygulamasının değil, ihtiyaç duyduğu her bir bağımlılığın oluşturma maliyetini görebilirsiniz.

  • Artık yalnızca türü örneklendirmenin maliyetini değil, aynı zamanda bir izdeki tüm bağımlılıklarını da görebilirsiniz. Bu gerçekten çok güçlü bir özellik.

  • Bir finans uygulaması olan Wise, bu bilgileri kullanarak uygulama başlatma süresini %45 oranında iyileştirdi.

  • Uygulama başlatma sırasında ilk kullanıma hazırlanması gerekmeyen şeyleri erteleyebildiler ve ayrıca yanlış kapsamlı bazı öğeler belirlediler. Singleton olması gereken şeyler yanlışlıkla singleton değildi ve bunlar kodunuzda görüp kolayca düzeltebileceğiniz şeylerdir.

  • Girişim metriklerine bakarsanız gerçekten etkileyici olduklarını görürsünüz.

  • İlk kareye kadar geçen süreyi iyileştirmekle kalmayıp tam görüntüye kadar geçen süreyi de iyileştirdiler.

  • Başka bir iş ortağı olan BandLab da CI'da aynı bilgileri kullanıyor.

  • Böylece, her bir @Inject bağlamanın maliyetini bilmekle kalmaz, aynı zamanda bu maliyete hangi iş parçacığının neden olduğunu da bilirsiniz.

  • Bunu öğrendikten sonra ana iş parçacığındaki tüm pahalı @Inject bağlamaları bulabilirsiniz. CI'nızda bir sorgu çalıştırarak tüm pahalı bağlamaların listesini alabilir ve bunları, bağlamaları oluşturan değişiklikle ilişkilendirebilirsiniz. Ardından, asıl değişikliği suçlayıp düzeltmeye çalışabilirsiniz.

Bağlam yayma, eş yordamlar ve Jetpack Compose

  • Rahul Ravikumar

    Anladım.

  • Şimdiye kadar Tracing 1'e kıyasla iyileştirdiğimiz her şeyden bahsettim. Şimdi ise Tracing 2'de bulunan ve daha önce mümkün olmayan yeni özelliklerden bahsedeceğim.

  • Temel özelliklerden biri, bağlam yaymadır. Modern uygulamalar giderek daha karmaşık hale geldiğinden iş yükleri birden fazla iş parçacığı, eş yordam ve işlemde çalışır.

  • Bir isteğin her bir iş parçacığı ile işlem arasında nasıl yayıldığını görselleştirmek istiyorsunuz.

  • Bağlam yayılımı da bunu mümkün kılar.

  • Yani size sadece dilimlerin listesini verip neyin neye sebep olduğunu söylemeseydim bu bilgi faydalı olurdu ama üzerinde düşünmek çok kolay olmazdı.

  • Ancak bunun yerine, size bunun gerçekleşen olayların nedensel zinciri olduğunu söylersem, neler olduğunu anlamanız ve her bir dilimin maliyetini ilişkilendirmeniz çok daha kolay olur.

  • Bağlam yayma, bu bilgileri kullanılabilir hale getirir.

  • Bağlam yayılımının tam olarak desteklendiğini bilmek sizi mutlu edecektir. Bu nedenle, gerçek bir örnek verelim.

  • com.example.app Perfetto izine tekrar baktığımızda, performInitialize işleminin çok uzun sürdüğünü ve maliyeti ertelemek veya farklı bir iş parçacığına taşımak istediğinizi varsayalım.

  • Bunu kesinlikle yapabilirsiniz.

  • performInitialize adlı iletiyi farklı bir ileti dizisine taşıdığımı varsayalım.

  • Bu durumda, dilimin hiyerarşik yapısını kaybetmiş olursunuz.

  • Bu nedenle, koda bakmadığınız sürece performInitialize işleminin initializeComponent tarafından tetiklendiğini anlayamazsınız.

  • İdeal bir dünyada, A'nın B'ye neden olduğunu gösteren bir ok istersiniz ve ardından olayların nedensel zinciri hakkında bir tür akıl yürütebilirsiniz.

  • Platformdaki bağlayıcı işlemleri için bunu yaptığımız bir sistem izi bile görmüş olabilirsiniz.

  • Burada, Compose karşılaştırmasının bir kare hazırlamak için system_server ile bir bağlayıcı işlemi yaptığını görebilirsiniz.

  • Platform izleme açısından bu her zaman mümkündü ancak araçları uygulama geliştiricilerin kullanımına sunmamıştık.

  • Artık Kotlin eş yordamı bağlam yayma, Tracing 2.0'da tam olarak destekleniyor.

  • Herhangi bir şey yapmanız gerekmiyor.

  • Kutudan çıkarmanız yeterli.

  • Burada, fetchProfile adında tek bir askıya alma yöntem çağrımız var.

  • Başka bir askıya alma yöntemi olan client.get yöntemini çağırır ve ardından yanıtın serileştirilmesini kaldırmak için Dispatchers.Default yöntemine geçer.

  • Bu, muhtemelen her gün karşılaştığınız, çok standart bir eş yordam kodudur.

  • Şimdi, bunu izlemek istediğimizi varsayalım.

  • İzleme bölümü ekleriz.

  • Burada, askıya alma kod bloğu olduğu için izleme yerine traceCoroutine API'sini kullanacağız. Ardından, bağlamı Dispatchers.Default olarak değiştirmeden önce iç çağrı için aynı traceCoroutine API'sini kullanarak başka bir iç izleme bölümü ekleyeceğiz.

  • İzleme sırasında şuna benzer bir şey görürsünüz.

  • İşimizin worker-1'de başladığını, ardından bağlam değiştirerek worker-3'e geçtiğini göreceksiniz. İzde bunu gösteren faydalı oklar da göreceksiniz.

  • Ayrıca, ortadaki kareyi yakınlaştırırsanız deserialize işleminin aslında worker-1'de başladığını ve withContext çağrısının bağlam geçişine neden olduğunu görebilirsiniz. Ardından, worker-3'te devam etti ve fetchProfile, worker-3'te devam etti çünkü eş yordam mekanizması, gerçekleşen bağlam geçişlerinin sayısını en aza indirmek istiyor.

  • Bir eş yordamın tam olarak ne zaman askıya alındığını, ne zaman devam ettirildiğini ve olayların tüm nedensel zincirini görebilirsiniz.

  • Tracing 2'nin sağladığı bir diğer özellik de izlere özel meta veriler ekleyebilmenizdir.

  • Geçmişte, kullanabileceğiniz tek araç izleme bölümünün adıydı. Ancak artık buna ek olarak, istediğiniz kadar meta veri girişi eklemenize olanak tanıyan bir meta veri bloğu da ekleyebilirsiniz.

  • Bunu da izlemeye ekleyebilirsiniz.

  • Gerçek ize baktığınızda, eklediğiniz tüm meta verilerin tüm araçların kullanması için izde olduğunu görebilirsiniz.

  • Artık bildiğiniz her şeyi, her zaman eklemek istediğiniz tüm ek bilgileri ekleyebilirsiniz.

  • İzlemenin mümkün kıldığı soyut özelliklerden bahsettim. Ancak tüm bu özelliklerin en iyi şekilde kullanıldığı yer, Jetpack Compose'daki yeni bir özellik olan yeniden oluşturma izleme.

  • Bu özellik, Compose 1.13 sürümünde sunulduğu için hemen kullanmaya başlayabilirsiniz.

  • Örneğin,

  • Bu, muhtemelen hepinizin aşina olduğu Oluşturma İzleme'dir.

  • Bu özellik, Compose'un ilk günlerinden beri mevcuttur.

  • Bu, bir composable'ın ve tüm alt dilimlerinin göreceli maliyetini ve her birinin gerçekleştiği iş parçacığındaki maliyetini gösterir.

  • Bu oldukça basit bir işlem.

  • Ancak bağlamı size söylemez.

  • Bunun neden olduğunu söylemez.

  • Öğelerin neden yeniden oluşturulduğunu belirtmez.

  • Uzaklaştırdığımda, bir önceki slaytta baktığımız ilgi alanını görüyoruz.

  • Sol tarafta ise bir giriş gönderme etkinliğinin gerçekleştiğini görebilirsiniz.

  • Belki de bazı durumları değiştiren ve yeniden oluşturmaya neden olan şey budur.

  • Ancak bu net değil.

  • Kesin olarak bilmiyorsunuz.

  • Ancak yeniden oluşturma izleme özelliği sayesinde artık izlemeye özel meta veriler ekleyerek yeniden oluşturma işlemlerinin tam olarak neden gerçekleştiğini öğrenebilirsiniz.

  • Bu sayede, bu etkinliklerin birbiriyle ilişkili olduğunu kolayca anlayabilirsiniz.

  • Bunları tıkladığınızda tam olarak hangi durumun değiştiğini görebilirsiniz.

  • Bu, bir durum olduğunu, daha önce doğru olan ve yanlış olarak değiştirilen değişken bir durum değeri olduğunu söyler.

  • Bununla da kalmayıp hataya neden olan çağrı yığınını da tam olarak gösteririz.

  • Burada, AbstractClickableNode.performClick gerçekleştiğini, bunun da değiştirilebilir durumun değişmesine ve yeniden oluşturmanın gerçekleşmesine neden olduğunu görebilirsiniz.

  • Bu gerçekten çok güzel bir özellik. Daha önce böyle bir şey yapamıyorduk.

  • Bu araçlar da kullanılabilir. Bu işlevlerin tümü yeni Android Performance Analyzer aracında da kullanılabilir. Temsilci araçlarından bazılarını denemek isterseniz bu aracı kullanabilirsiniz.

  • Doğru.

  • Kotlin eş yordamları için bağlam yayılımının tam olarak desteklendiğini söylemiştim.

  • Peki ya eş yordamlar ve eş yordam olmayan kodların karışımını kullanan kodlar? Ya da kendi başınıza iş parçacıkları çalıştırıyorsanız veya bir nedenle geri çağırmaları kullanan çok eski bir kahverengi alan kodunuz varsa?

  • Anladım.

  • İyi haber şu ki bağlam yayılımının tüm avantajlarından yararlanmaya devam edebilirsiniz.

  • Diyelim ki geri çağırma ve yürütücü kullanan bir kahverengi alan API'miz var.

  • Uygulama executor.execute kullanır, uygulama ayrıntısı olan runCatching yöntemini çağırır, yanıtı alır ve ardından geri çağırmaya yanıtı bildirir.

  • Anladım.

  • Bunu izlemek istersem Tracer.global.trace yapıp bir etiket ekler ve bloğu çevrelerim.

  • Ancak olayların nedensel zincirini de korumak istediğim için yayılma jetonu adı verilen yeni ve isteğe bağlı bir türü kabul edeceğim.

  • Ardından, jetonu dahili izleme API'sine ileteceğim.

  • Bu yöntemi çağıran kişi, isteğe bağlı olarak yayılma jetonunu bana verebilir. Böylece, gerçekleşen olayların nedensel zincirini koruyabilirim.

  • Anladım.

  • Bu API'yi çağıran API, askıya alma API'si olabilir.

  • Burada, geri çağırma ve yürütücü kullanan API'yi çağıracak bir askıya alma işlevi profileRequest var.

  • Burada, askıya alma dünyası ile geri çağırma dünyası arasında köprü kurduğum için suspendCoroutine oluşturucusunu kullanacağım.

  • Bir devamlılık elde edeceğim, ardından API'yi çağıracağım ve yanıtı aldıktan sonra geri çağırmada devamlılığı sürdüreceğim.

  • Tanımladığım yürütücünün adı profileRequestContext.

  • Tek iş parçacıklı bir yürütücüdür.

  • traceCoroutine, eş yordam bağlamına bir yayılma jetonu yerleştirdiği için yayılma jetonunu eş yordam bağlamından alıp eski API'ye giriş olarak iletebilirim. Böylece olayların nedensel zincirini koruyabilirim.

  • İzde bu durum çok net bir şekilde görülüyor.

  • Burada, worker-3'te başlayan, bağlam geçişi yaptıktan sonra tek iş parçacıklı yürütücüye geçen ve ardından worker'da devam eden bir işlem var.

  • Bu oldukça kullanışlı bir özellik.

Genel izleme ve özel başlatma

  • Rahul Ravikumar

    Anladım.

  • Yapabileceğiniz diğer işlemlerden biri de Tracer.global özelliğini özelleştirmektir.

  • Tracing 2.0 API, Tracer.global için oldukça iyi varsayılan değerler sunar ancak isterseniz bunları özelleştirebilirsiniz.

  • Ayrıca Tracing 2.0, JVM ve Android'i destekler. Çünkü izlemenin hem Java hem de Android kitaplıkları için tam olarak desteklenmesini istiyoruz.

  • Başlatma işleminin üç adımı vardır. İlk olarak izleme havuzu oluşturursunuz.

  • İzleme havuzu, izleme paketlerinin depolanma şeklidir.

  • Kablo biçimini ve çıkış izlerinin depolandığı konumu tanımlar.

  • Perfetto biçimini destekleyen bir izleme havuzu için kullanıma hazır bir uygulama sunuyoruz ancak elbette kendi izleme havuzunuzu da yazabilirsiniz.

  • Bu, Tracing 1'de kullanılabilen tek arka uç olan atrace'in sorununu çözmeye çalışmaya dayanır.

  • Bu sorunu çözmek istedik.

  • Artık OpenTelemetry havuzu yazmak veya kendi havuzunuzu kullanmak isterseniz bunu yapabilirsiniz.

  • Bu ayarı geçersiz kılabilirsiniz.

  • Bir havuz oluşturduktan sonra izleme sürücüsü oluşturup havuzu bu sürücüye verebilirsiniz.

  • Dilerseniz etkinleştirmek istediğiniz kategorileri de seçebilirsiniz.

  • Kategoriler bu aşamada gerçekten çok işe yarar.

  • Bu nedenle, yayınlama sırasında bazı kategorilerin hata ayıklamaya kıyasla daha önemli olduğuna karar verebilir ve bu kategorileri etkinleştirmek istediğinizi belirtebilirsiniz.

  • "Nereden geldiklerine bakılmaksızın tüm kategorileri etkinleştirmek istiyorum" da diyebilirsiniz.

  • Bu da tamamen normaldir.

  • İzinize genel olan özel özellikler de ekleyebilirsiniz.

  • Böylece, derleme sürümü, türü veya bir izlemeye eklemek istediğiniz diğer meta veriler gibi bilgileri addAttribute API'sini kullanarak ekleyebilirsiniz.

  • Son olarak, setGlobalTracer yöntemini çağırarak bir izleyici kaydedebilirsiniz.

  • Tracer.global, izleyicinin bu örneğine bu şekilde bağlanır ve daha sonra işlem için kullanılabilir hale gelir.

  • Android'de süreçlerin yaşam döngüsü çok daha iyi tanımlandığından tek yapmanız gereken AbstractTraceDriver.Factory sınıfını uygulamak ve create yöntemini geçersiz kılmaktır. Daha önce yaptığınız her şeyi aynen yapabilirsiniz.

  • Yani önce havuzu, ardından sürücüyü oluşturursunuz.

  • Burada kaydolmanız gerekmez.

  • İlk olarak bu işlemin yapıldığını bildiğimiz için kaydı sizin yerinize biz yapacağız.

  • Anladım.

  • İzleme özelliğinin çoklu platformlarda kullanıma hazır olduğunu tekrar hatırlatmak isteriz.

  • Compose'un birden fazla platformda çalıştığını bildiğimiz için bu seçimi bilinçli olarak yaptık. Böylece mümkün olduğunca çok yerde izleme yapabilirsiniz.

  • Şu anda Android ve JVM'yi destekliyoruz ancak uygulamamız, gelecekte istediğimiz takdirde başka platformları da desteklememize olanak tanıyor.

Derleme aracı optimizasyonları (R8 ve metalava)

  • Rahul Ravikumar

    Android'de kaynak kodunu küçültmek ve optimize etmek için kullanılan R8 aracının Tracing 2.0'ı kullandığını bilmek sizi mutlu edecektir.

  • İzlerden yararlanarak R8'i, kodunuzu %25 daha hızlı küçültecek ve optimize edecek şekilde optimize ettik.

  • Bu da derleme sürelerinin kısalması ve optimizasyon aşamaları için daha az beklemeniz anlamına gelir.

  • R8'de yaptığımız her optimizasyonu tek tek ele almayacağım. İzlemenin neler yapabileceğini göstermek için sadece bir tanesini inceleyeceğim.

  • Yani R8, özünde kaynaktan kaynağa dönüştürücüdür.

  • Böylece bir grup JAR elde edersiniz ve bunları küçültüp optimize ederek dex'leyebileceğiniz başka bir JAR grubu oluşturursunuz.

  • Burada AGP, yalnızca uygulamanızın değil, tüm bağımlılıklarının JAR'larını okuyarak başlar.

  • Bu nedenle, tüm giriş JAR'larını okumaya başlamak için Gradle çalışanlarını kullanır.

  • Okumak istediğiniz çok sayıda JAR var.

  • JAR'ları okumayı bitirdikten sonra R8, kodu ayrıştırmaya ve kodunuzun temsil ettiği şeyin ve tüm giriş noktalarının bir modelini oluşturmaya başlar. Böylece kodunuzu optimize etmeye ve küçültmeye başlayabilir.

  • Bu, R8'in optimizasyon sürecini başlatmaya gerçekten hazır olduğu zamanı temsil eden dilimdir, değil mi?

  • Ortada boş bir alan olduğunu görebilirsiniz. Bu kullanılmayan CPU süresinin neden olduğunu merak edebilirsiniz.

  • Bunun nedeni, eski API'nin çalışma şekliydi. Eski API'de, herhangi bir şeyi ayrıştırmadan önce tüm çalışanların tüm dosyalarını okumasını bekliyorduk.

  • Bu sorunu çözebilirdik ve tam olarak bunu yaptık.

  • AGP 9'da, giriş JAR'larını okumayı bitirdiğimiz anda işlemeye başladığımızı görebilirsiniz.

  • Ayrıca her bir çalışanın girişlerini okumayı bitirmesini beklememiz gerekmedi.

  • Bu sayede tüm girişleri okumak için beklediğimiz süre önemli ölçüde azaldı.

  • Bu, izlemeye baktığınızda çok net bir şekilde görebileceğiniz bariz bir optimizasyondur. Ancak neyin optimize edilmeye değer olduğunu görmek için yalnızca kaynak koduna baktığınızda o kadar net değildir.

  • AndroidX mühendisi olarak her gün kullandığımız bir diğer araç da Metalava'dır.

  • Metalava, sunduğumuz tüm API'lerin beklediğiniz API uyumluluk garantilerine sahip olduğundan ve kaçınmak istediğimiz sorunlar olmadan harici kişiler tarafından tamamen kullanılabildiğinden emin olmak için kullandığımız bir araçtır.

  • Bu araç, her bir herkese açık API ve kısıtlanmış API'de çalışır. Bu nedenle, burada tasarruf ettiğimiz her zaman, aslında AndroidX mühendisi olarak geri kazandığımız zamandır.

  • Metalava, gönderim sonrası süreleri %15 oranında iyileştirmek için izleme özelliğini de kullandı.

  • Metalava, iki tür kontrol gerçekleştirir: Birincisi kısıtlanmış API'leri, ikincisi ise herkese açık API'leri kontrol eder.

  • Ancak bir kalıp fark etmiş olabilirsiniz.

  • Bu kontrolleri iki kez çalıştırmak için bir dizi kurulum yapıyoruz.

  • Yani tüm program girişleri okunur, PSI'yı (program yapısı arayüzü) oluştururuz. Bu, kodunuzun şeklini tam olarak gösterir.

  • Ardından, istediğimiz tüm lint kontrollerini uygulamaya başlamadan önce AST'yi oluştururuz.

  • Bu maliyetli işi iki kez yapıyoruz.

  • Bu sorunu nasıl çözdük?

  • Bunu yalnızca bir kez yaptık.

  • Bu nedenle, tüm bu kurulum çalışmalarını iki kez yapmak yerine yalnızca bir kez yaptık ve bu girişleri hem kısıtlanmış kontroller hem de herkese açık kontroller için yeniden kullandık. Böylece tüm bu tasarrufları elde ettik.

  • Evet.

  • Anladım.

En iyi uygulamaları izleme ve karşılaştırma

  • Rahul Ravikumar

    İzleme 2.0'ın neler yapabileceğini gösterdiğime göre, izlemenin önemli olduğunu bilmek kadar neyi izleyeceğinizi bilmenin de önemli olduğunu belirtmek isterim.

  • Her yere iz bırakmak istemezsiniz.

  • Seçim yaparken çok dikkatli olmanız gerekir. Bu nedenle, izlemeye değer olan konularla ilgili bazı yönergeler vermeye çalışacağım.

  • Bu nedenle, yapmanız gereken ilk şey izinizde açıklanamayan boşluklar bulmaktır.

  • İş parçacıklarınız çalışır veya çalıştırılabilir durumdayken sistem izlemenizde belirgin boşluklar görürseniz, bunları açıklayamazsanız ve uygulamanızın ne yaptığını bilmiyorsanız bu durumu araştırmanız gerekebilir.

  • Bu noktada, sistem iziyle üst üste binen bir yöntem izi alıp izlemeye değer olanları görebilir ve ilgili izleme bölümlerini ekleyebilirim.

  • Ayrıca kullanıcı yolculuklarına göre önceliklendirme yapmak istiyorsunuz.

  • Bu nedenle, uygulama başlatma süresine bakmanız gerekir.

  • Uygulamanızın temel kullanıcı yolculuklarını incelemek ve bunları bir izlemeye bakarak açıklayıp açıklayamayacağınızı anlamak istiyorsunuz.

  • Dolayısıyla, bir şey hakkında mantık yürütemediğiniz her an, izleme yapmaya değerdir.

  • Ayrıca, bir izdeki derin çağrı yığınlarına veya açıklanamayan CPU kullanımına bakıp tam olarak ne olduğunu anlamaya çalışmalı ve ardından kod tabanınızın bu bölümlerini izlere dönüştürmelisiniz.

  • Böylece bunları takip edebilirsiniz.

  • Ardından, iş parçacıklarınızın neden uyku moduna geçtiğini anlamanız gerekir.

  • G/Ç'yi, bağlayıcı işlemini veya gerçekleşmesini beklediğiniz bazı harici giriş etkinliklerini bekliyor olmaları gerekir.

  • Ancak açıklanamayan uyku sorunlarınız varsa bunlar kesinlikle araştırılmaya değerdir çünkü altında yatan başka bir neden olabilir.

  • Ardından, bu koddaki tüm izleme bölümlerini ekledikten sonra, bunları karşılaştırma ölçütlerine dönüştürmeniz gerekir. Böylece, bunlardaki değişiklikleri izleyebilirsiniz.

  • Böylece kod tabanınız geliştikçe metriklerin değişip değişmediğini, gösterge tablolarınızın büyük değişiklikleri gerçekten yansıtıp yansıtmadığını görebilirsiniz. Bu sayede önemli bir şeyin değiştiğini anlarsınız.

  • Dilerseniz önceki tüm adımları atlayıp bu işlemi temsilcinizin yapmasını sağlayabilirsiniz.

  • Bu yönergeleri beceriye dönüştürün, ardından favori temsilcinize yönlendirin ve denemesini sağlayın.

  • Evet.

Kurulum, özet ve sonuç

  • Rahul Ravikumar

    İzlemenin değerli bir çalışma olduğuna ve bunu yapmanız gerektiğine sizi ikna edebildiysem proje kurulumuna geçelim.

  • Aslında oldukça basit.

  • İzleme, geleneksel bir Java kitaplığıdır. Perfetto uyumlu izleme sürücüsü ve izleme kombinasyonu olan androidx.tracing:tracing-wire için bir bağımlılık tanımlarsınız. Mevcut kararlı sürüm 2.0.5'tir.

  • Java kitaplığı kullanıyorsanız da aynı şey geçerlidir. Bu API, tamamen çoklu platform desteklidir.

  • Bu özelliği, uygun olduğunda diğer platformlarda da kullanıma sunmak istiyoruz.

  • Evet, kısaca bir özet geçmek istedim.

  • Eklediğimiz tüm bu yeni ve harika özelliklerden bahsettim.

  • Bu nedenle, bağlam yayma gerçekten çok güçlüdür.

  • Özel bilgiler, meta veriler, çağrı yığını bilgileri ve diğer her türlü bilgiyi yerleştirebiliriz.

  • Bahsetmediğim daha çok şey var.

  • İzleme biçimini ve izleme havuzunuzu değiştirebilir, izleme verilerinizi OpenTelemetry'ye taşıyabilirsiniz.

  • Bunların hepsini yapabilirsiniz.

  • İzleme, çoklu platformda kullanılabilir.

  • Bu da yine çok bilinçli bir karar çünkü mümkün olduğunca çok kişinin bu özellikten yararlanabilmesini istiyoruz.

  • Perfetto, AndroidX Benchmarks, yeni performans analiz aracı veya eski Android Profiler gibi sunduğumuz tüm araçlar Tracing 2.0'ı destekler.

  • Dinlediğiniz için çok teşekkür ederiz.

  • Umarım Geliştirici Zirvesi'nde keyifli vakit geçirirsiniz. Teşekkürler.