🚀Kotlin Performans Optimizasyonu: 15 Adımda Uygulamanızı Daha İyi Hale Getirin!

Ali Osman ARSLAN
Huawei Developers - Türkiye
5 min readDec 29, 2023
Android App Performans

Giriş

Kotlin, temiz ve etkili bir kod yazma konusunda gelişmiş bir dil olmasına rağmen, performansı artırmak için belirli stratejileri takip etmek önemlidir. Bu rehberde, Kotlin uygulamalarınızın performansını optimize etmek için kullanabileceğiniz 15 en iyi uygulama bulunmaktadır.

Temel İpuçları

  1. ‘val’ Kullanımı

val (immutable) kullanmak, değişkenin bir kez atanmasını ve sonrasında değiştirilememesini sağlar. Bu, kodun daha okunabilir ve güvenilir olmasını sağlar. Ayrıca, derleyici, değişmeyen değerlere daha iyi optimizasyon yapabilir.

// Kötü
var x = 5

// İyi
val x = 5

2. Gereksiz Nesne Oluşturmadan Kaçının

Nesne oluşturmak bellek kullanımını artırabilir ve gereksiz işlem gücü harcanmasına neden olabilir. Özellikle döngülerde veya yoğun kullanılan bölgelerde gereksiz nesne oluşturmaktan kaçınılmalıdır.

// Kötü
val list = ArrayList<String>()

// İyi
val list = mutableListOf<String>()

3. Uzun if-else Döngüleri Yerine When Kullanın

Uzun if-else döngülerinin yerine when kullanmak, kodunuzu daha temiz, okunabilir ve bakımı daha kolay hale getirir. Ayrıca, when ifadesi Kotlin'in güçlü ve esnek özelliklerinden biridir, bu nedenle onu etkili bir şekilde kullanmak genellikle daha iyi bir kod üretir.

// Kötü
fun describeNumber(number: Int): String {
if (number == 1) {
return "Bir"
} else if (number == 2) {
return "İki"
} else if (number == 3) {
return "Üç"
} else {
return "Diğer"
}
}

// İyi
fun describeNumber(number: Int): String {
return when (number) {
1 -> "Bir"
2 -> "İki"
3 -> "Üç"
else -> "Diğer"
}
}

4. Kod Nesting’i Azaltın

Gereksiz derecede iç içe geçmiş kod blokları, kodun okunabilirliğini azaltır ve gereksiz karmaşıklığa yol açabilir. İç içe geçmiş blokları azaltmak, kodun daha anlaşılır olmasını sağlar ve potansiyel performans iyileştirmelerine olanak tanır

// Kötü
fun processUserData(user: User?) {
user?.let {
it.address?.let {
// kod bloğu
}
}
}

// İyi
fun processUserData(user: User?) {
user?.address?.let {
// kod bloğu
}
}

5. Koleksiyon Operasyonlarını Optimize Edin

Koleksiyon operasyonlarını doğru şekilde kullanmak, gereksiz döngüleri ve nesne oluşturmayı önleyerek performansı artırabilir. asSequence() kullanmak, işlemleri tembelliğe yönlendirir, böylece yalnızca gerektiğinde elemanları işler

// Kötü
val doubledNumbers = numbers.map { it * 2 }.filter { it > 10 }

// İyi
val doubledNumbers = numbers.asSequence().map { it * 2 }.filter { it > 10 }.toList()

6. Lazy Initialization

by lazy kullanmak, bir özelliğin değerine ihtiyaç duyulana kadar başlatılmasını sağlar. Bu, uygulama başlatma süresini ve bellek kullanımını azaltabilir.

// Kötü
val expensiveResource = ExpensiveResource()

// İyi
val expensiveResource by lazy { ExpensiveResource() }

7. Gereksiz Null Kontrollerinden Kaçının

Null kontrol operatörleri ve nullable tipler kullanmak, NullPointerException’ları önler ve kodun güvenli olmasını sağlar. Ancak, gereksiz yere null kontrolü yapmak da performans kaybına neden olabilir.

// Kötü
if (name != null) {
// kod bloğu
}

// İyi
name?.let {
// kod bloğu
}

8. Güvenli Dönüşüm Operatörünü Kullanın

as? operatörü, güvenli bir şekilde dönüşüm yapar ve eğer dönüşüm başarısız olursa null döner. Bu, ClassCastException'ları önler ve kodun daha güvenli olmasını sağlar.

// Kötü
val result: String = someObject as String

// İyi
val result: String? = someObject as? String

9. String Birleştirmeyi Optimize Edin

String birleştirme işlemleri, özellikle döngülerde, performans sorunlarına neden olabilir. "$" veya StringBuilder gibi daha etkili yöntemler kullanmak, bu durumu optimize eder.

// Kötü
val fullName = firstName + " " + lastName

// İyi
val fullName = "$firstName $lastName"

10. Object Initialization için apply Kullanın

Kotlin’deki apply fonksiyonu, bir nesnenin oluşturulması ve onun üzerinde belirli işlemlerin gerçekleştirilmesi için kullanılır. apply, nesne başlatma sürecini daha etkili ve okunabilir hale getirmek için tasarlanmış bir fonksiyondur. İşte apply fonksiyonunu kullanmanın bazı avantajları:

// Kötü
val person = Person()
person.name = "John"
person.age = 30
person.city = "New York"

// İyi
val person = Person().apply {
name = "John"
age = 30
city = "New York"
}

11. Asenkron Programlamada Coroutines Kullanın

Coroutines, asenkron programlamayı kolaylaştırır ve daha verimli bir şekilde iş parçacıklarını yönetir. Callback’ler veya geleneksel thread yönetimi yerine kullanmak, kodunuzu daha etkili hale getirebilir.

// Kötü
fun fetchData(callback: (result: String) -> Unit) {
// kod bloğu
callback("Sonuç")
}

// İyi
suspend fun fetchData(): String {
// kod bloğu
return "Sonuç"
}

12. Veritabanı Erişimini Optimize Edin

Etkin sorgu kullanımı ve veritabanı erişiminde performanslı kütüphaneleri seçmek, uygulamanızın veritabanı performansını artırabilir.

// Kötü
val result = database.query("SELECT * FROM table")

// İyi
val result = userDao.getAllUsers()

13.Cache Kullanılan Değerleri

Değerleri önbelleğe almak, tekrar tekrar aynı hesaplamaları yapmaktan kaçınarak performansı artırabilir. Bu örnekte, daha önce hesaplanan değerler bir önbellek içinde saklanır ve aynı giriş için tekrar hesaplama yapma ihtiyacını azaltır.

// Kötü
fun calculateExpensiveOperation(input: Int): Int {
// pahalı hesaplama
}

// İyi
val cache = mutableMapOf<Int, Int>()

fun calculateExpensiveOperation(input: Int): Int {
if (input !in cache) {
cache[input] = // pahalı hesaplama
}
return cache[input]!!
}

14. Kaynakları Etkin Bir Şekilde Yönetin

Kaynakları (dosya, ağ bağlantısı, vb.) etkin bir şekilde yönetmek, bellek sızıntıları ve performans sorunlarını önler. lateinit anahtar kelimesi, değişkenin daha sonra başlatılacağını belirtir ve böylece başlatılmadan kullanılmaya çalışılmadan önce kontrol sağlar.

// Kötü
var file: File? = null

// İyi
lateinit var file: File

// Dosyayı kullanmadan önce kontrol etmek için
if (!::file.isInitialized) {
file = File("dosya_yolu")
}

15. Güncel Kütüphane ve Araçları Kullanın

Kotlin dilinde ve kullanılan kütüphanelerde sürekli olarak iyileştirmeler ve güncellemeler yapılır. Bu güncellemeler, performans iyileştirmeleri içerebilir. Güncel kütüphaneleri ve araçları kullanmak, kodunuzun en son performans avantajlarından faydalanmasını sağlar.

Sonuç

Kotlin, temiz ve etkili bir kod yazma konusunda güçlü bir dil olmasına rağmen, performansı artırmak ve kodu daha okunabilir hale getirmek için belirli stratejilere başvurmak önemlidir. Bu rehberde paylaşılan 15 Kotlin performans optimizasyonu yönerisi, geliştiricilere kodlarını optimize etme ve daha etkili hale getirme konusunda rehberlik etmektedir.

  • Okunabilirlik ve Bakım Kolaylığı: val kullanımı, Kotlin Standart Kütüphane fonksiyonları ve when ifadesi gibi öneriler, kodunuzu daha okunabilir ve bakımı daha kolay hale getirir.
  • Performans Artırma Stratejileri: Lazy initialization, düzenli ifadelerin optimize edilmesi, veritabanı erişiminin optimize edilmesi gibi öneriler, uygulamanın performansını artırmak için etkili stratejiler sunar.
  • Kotlin Özelindeki İyi Uygulamalar: apply fonksiyonu gibi Kotlin diline özgü araçları kullanmak, nesne başlatma ve konfigürasyonunu optimize etmek ve kodu daha sade hale getirmek için önemlidir.

Sonuç olarak, Kotlin geliştiricileri, performansı artırma ve kodlarını daha etkili ve okunabilir hale getirme konusunda bu yönergeleri kullanabilirler. Ancak, her uygulama benzersizdir ve performans iyileştirmeleri, kodun profillemesi ve ölçümü üzerine dayanmalıdır. Öneriler, kod yazma sürecini iyileştirmek ve temel prensiplere odaklanmak için bir rehber olarak kullanılmalıdır.

Referanslar

--

--