Derlemenizi profilleyin

Daha büyük projeler veya çok sayıda özel derleme mantığı uygulayan projeler, darboğazları bulmak için derleme sürecini daha ayrıntılı incelemenizi gerektirebilir. Bunu yapmak için Gradle'ın derleme yaşam döngüsünün her aşamasını ve her derleme görevini yürütmesinin ne kadar sürdüğünü profillemeniz gerekir. Örneğin, derleme profiliniz Gradle'ın projenizi yapılandırmak için çok fazla zaman harcadığını gösteriyorsa özel derleme mantığını yapılandırma aşamasından çıkarmanız gerekebilir. Ayrıca, mergeDevDebugResources görevi derleme süresinin büyük bir kısmını tüketiyorsa resimlerinizi WebP'ye dönüştürmeniz veya PNG sıkıştırmayı devre dışı bırakmanız gerekebilir.

Android Studio 4.0 veya sonraki bir sürümü kullanıyorsanız derleme performansı sorunlarını incelemenin en iyi yolu Derleme Analiz Aracı'nı kullanmaktır.

Ayrıca, derlemenizi Android Studio dışında profillemek için iki seçenek vardır:

  1. Derlemenizin derinlemesine analizi için güçlü bir araç olan bağımsız gradle-profiler aracı.

  2. Gradle komut satırından kullanılabilen kullanışlı bir araç olan Gradle --profile seçeneği.

Bağımsız gradle-profiler aracını kullanma

Size en iyi derleme hızını sağlayan proje kurulumunu bulmak için Gradle derlemeleriyle ilgili profil oluşturma ve karşılaştırma bilgilerini toplayan bir araç olan Gradle profiler'ı kullanmanız gerekir. Gradle profiler, derleme senaryoları oluşturmanıza ve bunları birden çok kez çalıştırmanıza olanak tanır. Böylece sonuçlar arasında yüksek varyans oluşmasını önler ve sonuçların tekrarlanabilirliğini sağlar.

Temiz ve artımlı derlemeler hakkında bilgi toplamak için karşılaştırma modu, CPU anlık görüntüleri de dahil olmak üzere çalıştırmalar hakkında daha ayrıntılı bilgi toplamak için ise profil oluşturma modu kullanılmalıdır.

Karşılaştırma için proje kurulumu yapılandırmalarından bazıları şunlardır:

  • Eklenti sürümleri
  • Gradle sürümleri
  • JVM ayarları (yığın boyutu, permgen boyutu, çöp toplama vb.)
  • Gradle çalışanlarının sayısı (org.gradle.workers.max)
  • Performansı daha da optimize etmek için eklenti bazında seçenekler

Başlarken

  • Bu talimatları uygulayarak gradle-profiler'ı yükleyin.
  • Çalıştır: gradle-profiler --benchmark --project-dir <root-project> :app:assembleDebug

--benchmark, projeyi değiştirmeden görevi birden çok kez çalıştırdığı için bu işlem, tamamen güncel bir derlemeyi karşılaştırır. Ardından, profile-out/ dizini altında derleme sürelerini gösteren bir HTML raporu oluşturur.

Karşılaştırma için daha yararlı olabilecek başka senaryolar da vardır:

  • Çalışmalarınızın çoğunu yaptığınız bir sınıftaki yöntem gövdesinde kod değişiklikleri.
  • Projeniz genelinde kullanılan bir modüldeki API değişiklikleri. Kendi kodunuzda yaptığınız değişikliklere kıyasla daha az sıklıkta gerçekleşse de bu değişikliklerin etkisi daha büyüktür ve ölçülmesi faydalıdır.
  • Kullanıcı arayüzü çalışmasında yineleme simülasyonu yapmak için düzenleme düzenlemeleri.
  • Çeviri işiyle uğraşmayı simüle etmek için dize düzenlemeleri.
  • Derlemenin kendisinde yapılan değişiklikleri (ör. Android Gradle eklentisi güncellemesi, Gradle güncellemesi veya buildSrc altındaki kendi derleme kodunuzda yapılan düzenlemeler) simüle etmek için derlemeleri temizleyin.

Bu kullanım alanlarını karşılaştırmak için gradle-profiler yürütme işlemini yönlendirmek amacıyla kullanılacak ve kaynaklarınızda uygun değişiklikleri uygulayacak bir senaryo oluşturabilirsiniz. Aşağıdaki bölümlerde sık karşılaşılan bazı senaryolar açıklanmaktadır.

Farklı bellek/CPU ayarlarının profilini çıkarma

Farklı bellek ve CPU ayarlarını karşılaştırmak için org.gradle.jvmargs için farklı değerler kullanan birden fazla senaryo oluşturabilirsiniz. Örneğin, aşağıdaki senaryoları oluşturabilirsiniz:

# <root-project>/scenarios.txt
clean_build_2gb_4workers {
    tasks = [":app:assembleDebug"]
    gradle-args = ["--max-workers=4"]
    jvm-args = ["-Xmx2048m"]
    cleanup-tasks = ["clean"]
}
clean_build_parallelGC {
    tasks = [":app:assembleDebug"]
    jvm-args = ["-XX:+UseParallelGC"]
    cleanup-tasks = ["clean"]
}

clean_build_G1GC_4gb {
    tasks = [":app:assembleDebug"]
    jvm-args = ["-Xmx4096m", "-XX:+UseG1GC"]
    cleanup-tasks = ["clean"]
}

gradle-profiler --benchmark --project-dir <root-project> --scenario-file scenarios.txt komutunu çalıştırdığınızda üç senaryo çalıştırılır ve bu kurulumların her biri için :app:assembleDebug komutunun ne kadar sürdüğünü karşılaştırabilirsiniz.

Farklı Gradle eklentisi sürümlerinin profilini oluşturma

Gradle eklentisinin sürümünü değiştirmenin derleme sürelerini nasıl etkilediğini öğrenmek için bunu karşılaştıran bir senaryo oluşturun. Bunun için, eklenti sürümünün senaryodan yerleştirilebilir hale getirilmesi amacıyla biraz hazırlık yapılması gerekir. Kök build.gradle dosyanızı değiştirin:

# <root-project>/build.gradle
buildscript {
    def agpVersion = providers.systemProperty("agpVersion").forUseAtConfigurationTime().orNull ?: '4.1.0'

    ext.kotlin = providers.systemProperty('kotlinVersion').forUseAtConfigurationTime().orNull ?: '1.4.0'

    dependencies {
        classpath "com.android.tools.build:gradle:$agpVersion"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin"
    }
}

Artık senaryo dosyasından Android Gradle eklentisi ve Kotlin Gradle eklentisi sürümlerini belirtebilir ve senaryonun kaynak dosyalara yeni bir yöntem eklemesini sağlayabilirsiniz:

# <root-project>/scenarios.txt
non_abi_change_agp4.1.0_kotlin1.4.10 {
    tasks = [":app:assembleDebug"]
    apply-abi-change-to ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
    System-properties {
      "agpVersion" = "4.1.0"
      "kotlinVersion" = "1.4.10"
}

non_abi_change_agp4.2.0_kotlin1.4.20 {
    tasks = [":app:assembleDebug"]
    apply-abi-change-to ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
    System-properties {
      "agpVersion" = "4.2.0-alpha16"
      "kotlinVersion" = "1.4.20"
}

Artımlı derlemenin profilini oluşturma

Derlemelerin çoğu artımlı olduğundan, bu senaryo profili çıkarılacak en önemli senaryolardan biridir. Gradle Profiler, artımlı derlemelerin profillemesi için kapsamlı destek sunar. Yöntem gövdesini değiştirerek, yeni bir yöntem ekleyerek veya bir düzen ya da dize kaynağını değiştirerek kaynak dosyada otomatik olarak değişiklikleri uygulayabilir. Örneğin, aşağıdaki gibi artımlı senaryolar oluşturabilirsiniz:

# <root-project>/scenarios.txt
non_abi_change {
    tasks = [":app:assembleDebug"]
    apply-non-abi-change-to = ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
}

abi_change {
    tasks = [":app:assembleDebug"]
    apply-abi-change-to = ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
}

layout_change {
    tasks = [":app:assembleDebug"]
    apply-android-layout-change-to = "app/src/main/res/your_layout_file.xml"
}
string_resource_change {
    tasks = [":app:assembleDebug"]
    apply-android-resource-value-change-to = "app/src/main/res/values/strings.xml"
}

gradle-profiler --benchmark --project-dir <root-project> --scenario-file scenarios.txt komutunu çalıştırdığınızda karşılaştırma verilerini içeren HTML raporu oluşturulur.

Artımlı senaryoları yığın boyutu, çalışan sayısı veya Gradle sürümü gibi diğer ayarlarla birleştirebilirsiniz:

# <root-project>/scenarios.txt
non_abi_change_4g {
    tasks = [":app:assembleDebug"]
    apply-non-abi-change-to ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
    jvm-args = ["-Xmx4096m"]
}

non_abi_change_4g_8workers {
    tasks = [":app:assembleDebug"]
    apply-non-abi-change-to ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
    jvm-args = ["-Xmx4096m"]
    gradle-args = ["--max-workers=8"]
}

non_abi_change_3g_gradle67 {
    tasks = [":app:assembleDebug"]
    apply-non-abi-change-to ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
    jvm-args = ["-Xmx3072m"]
    version = ["6.7"]
}

Temiz bir derlemenin profilini oluşturma

Temiz bir derlemeyi karşılaştırmak için gradle-profiler yürütmesini yönlendirmek üzere kullanılacak bir senaryo oluşturabilirsiniz:

# <root-project>/scenarios.txt
clean_build {
    tasks = [":app:assembleDebug"]
    cleanup-tasks = ["clean"]
}

Bu senaryoyu çalıştırmak için aşağıdaki komutu kullanın:

gradle-profiler --benchmark --project-dir <root-project> --scenario-file scenarios.txt

Gradle --profile seçeneğini kullanma

Gradle komut satırından derleme profili oluşturmak ve görüntülemek için aşağıdaki adımları uygulayın:

  1. Projenizin kök dizininde bir komut satırı terminali açın.

  2. Aşağıdaki komutu girerek temiz bir derleme gerçekleştirin. Derlemenizin profilini çıkarırken, profilini çıkardığınız her derleme arasında temiz bir derleme yapmanız gerekir. Bunun nedeni, bir görevin girişleri (ör. kaynak kodu) değişmediğinde Gradle'ın görevleri atlamasıdır. Bu nedenle, giriş değişiklikleri içermeyen ikinci bir derleme, görevler yeniden çalıştırılmadığı için her zaman daha hızlı çalışır. Derlemeleriniz arasında clean görevini çalıştırmak, derleme sürecinin tamamını profillemenizi sağlar.

    // On Mac or Linux, run the Gradle wrapper using "./gradlew".
    gradlew clean
    
  3. Ürün türlerinizden birinin (ör. "dev" türü) hata ayıklama derlemesini aşağıdaki işaretlerle çalıştırın:

    gradlew --profile --offline --rerun-tasks assemble<var>Flavor</var>Debug
    
    • --profile: Profil oluşturmayı etkinleştirir.

    • --offline: Gradle'ın online bağımlılıkları getirmesini devre dışı bırakır. Bu sayede, Gradle'ın bağımlılıklarınızı güncellemeye çalışmasından kaynaklanan gecikmeler, profil oluşturma verilerinizi etkilemez. Gradle'ın bağımlılıklarınızı indirip önbelleğe aldığından emin olmak için projenizi daha önce bir kez derlemiş olmanız gerekir.

    • --rerun-tasks: Gradle'ı tüm görevleri yeniden çalıştırmaya ve tüm görev optimizasyonlarını yoksaymaya zorlar.

  4. Derleme tamamlandıktan sonra Project (Proje) penceresini kullanarak project-root/build/reports/profile/ dizinine gidin (Şekil 1'de gösterildiği gibi).

    Şekil 1. Profil raporlarının konumunu gösteren proje görünümü.

  5. profile-timestamp.html dosyasını sağ tıklayın ve Tarayıcıda Aç > Varsayılan'ı seçin. Rapor, Şekil 2'de gösterilene benzer olmalıdır. Derlemeniz hakkında bilgi edinmek için rapordaki her sekmeyi inceleyebilirsiniz. Örneğin, Görev Yürütme sekmesinde Gradle'ın her derleme görevini yürütmesinin ne kadar sürdüğü gösterilir.

    Şekil 2. Raporu tarayıcıda görüntüleme

  6. İsteğe bağlı: Projenizde veya derleme yapılandırmanızda herhangi bir değişiklik yapmadan önce 3. adımdaki komutu tekrarlayın ancak --rerun-tasks işaretini atlayın. Gradle, girişleri değişmeyen görevleri yeniden yürütmeyerek zaman kazanmaya çalışır (bunlar, raporun Görev Yürütme sekmesinde UP-TO-DATE olarak gösterilir, Şekil 3'te gösterildiği gibi). Bu sayede, hangi görevlerin yürütülmemesi gerekirken yürütüldüğünü belirleyebilirsiniz. Örneğin, :app:processDevUniversalDebugManifest UP-TO-DATE olarak işaretlenmemişse derleme yapılandırmanızın her derlemede manifesti dinamik olarak güncellediği anlaşılabilir. Ancak :app:checkDevDebugManifest gibi bazı görevlerin her derleme sırasında çalıştırılması gerekir.

    Şekil 3. Görev yürütme sonuçları görüntüleniyor.

Derleme profili raporunuzu oluşturduktan sonra raporun her sekmesindeki bilgileri inceleyerek optimizasyon fırsatlarını aramaya başlayabilirsiniz. Bazı derleme ayarları, projeler ve iş istasyonları arasında farklılık gösterebilecek avantajlar sunduğundan deneme yapmayı gerektirir. Örneğin, büyük bir kod tabanına sahip projeler, kullanılmayan kodları kaldırmak ve uygulama boyutunu küçültmek için kod daraltma özelliğinden yararlanabilir. Ancak daha küçük projeler, kod daraltmayı tamamen devre dışı bırakmaktan daha fazla yararlanabilir. Ayrıca, Gradle yığın boyutunu artırmak (org.gradle.jvmargs kullanarak) düşük bellekli makinelerde performansı olumsuz etkileyebilir.

Derleme yapılandırmanızda değişiklik yaptıktan sonra önceki adımları tekrarlayıp yeni bir derleme profili oluşturarak değişikliklerinizin sonuçlarını inceleyin. Örneğin, Şekil 4'te, bu sayfada açıklanan temel optimizasyonlardan bazıları uygulandıktan sonra aynı örnek uygulama için oluşturulan bir rapor gösterilmektedir.

Şekil 4. Derleme hızını optimize ettikten sonra yeni bir raporu görüntüleme.