Sorunun tarihi:
Fonksiyonel programlama ve JVM'de lambda ifadelerinin popülaritesinin artmasıyla birlikte, anonim nesneler ve ek yöntem çağrıları için bir ek yük problemi ortaya çıktı. Java'da benzer bir durum, işlevsel arayüzler kullanıldığında görülmektedir. Kotlin, lambda fonksiyonlarının geçişinde gereksiz tahsislerden kaçınmak için inline anahtar kelimesini tanıttı.
Sorun:
Lambda parametreleri ile bir fonksiyon çağrısı, yığın üzerinde anonim nesneler oluşturur ve yığın derinliğini artırır, bu da kodun yürütülmesini yavaşlatır, özellikle döngülerde ve iç içe çağrılarda aktif olarak kullanıldığında.
Çözüm:
Kotlin, inline modifikatörü ile bir fonksiyon tanımlamanıza olanak tanır; bu durumda fonksiyonun gövdesi ve kendisine geçirilen lambda'lar, çağrı yerinde doğrudan yerleştirilir. Bu, derleyicinin ek tahsisten kurtulmasını ve özellikle kısa, sıkça çağrılan fonksiyonların (örneğin, koleksiyonları filtreleme) performansını artırmasını sağlar.
Kod örneği:
inline fun <T> Iterable<T>.myFilter(predicate: (T) -> Boolean): List<T> { val result = mutableListOf<T>() for (item in this) if (predicate(item)) result.add(item) return result } val filtered = listOf(1, 2, 3, 4).myFilter { it % 2 == 0 } println(filtered) // [2, 4]
Anahtar özellikler:
noinline ve crossinline parametrelerini kullanma imkanı.Herhangi bir işlevsel parametre veya generic tür T ile inline fonksiyon kullanılabilir mi?
Hayır, inline fonksiyonlar öncelikle lambda parametreleri üzerindeki çağrı yükünden tasarruf sağlar, ancak kendisi generic parametre (örneğin, T) inline edilmez — bunun için reified modifikatörü gereklidir. Basit T'ler için reified olmadan, tür bilgisi derleme aşamasında silinecektir.
Inline fonksiyon içinde dış kapsamdan bir değişkene closure tanımlamak ne olur?
Dış kapsamdan değişkenler inline ifadenin içine kopyalanır. Onlara yapılan tüm erişimler, sanki kod gerçekten yerleştirilmiş gibi çalışacaktır. Beklenmeyen yan etkiler olabileceğinden, beklemediğinizde bu durum garip davranışlara yol açabilir.
Java kodundan inline fonksiyonu çağırmak mümkün mü?
Evet, ancak bu, normal bir fonksiyon olarak derlenecek ve Java kodu inlining avantajlarını göremeyecektir. Kotlin, inline fonksiyonları yalnızca Kotlin kodu içinde kullanıldığında optimize eder.
return kullanırken yapılan hatalar — akış kontrolü yanlışlığıBir geliştirici, birkaç lambda filtreleme ve sonrası işlemi ile uzun bir fonksiyonu inline eder, hız artışı bekler. Kod uzun sürede derlenir, nihai APK/RAR/DEX önemli ölçüde artar ve hızda bir artış olmaz.
Artılar:
Eksiler:
Kısa dizi filtreleri için küçük bir inline fonksiyon gerçekleştirilmiştir, bu fonksiyon yüzlerce kez sıcak bir döngüde çağrılmakta — yürütme süresi kritik öneme sahiptir. Bellek tahsisi minimumdur, çünkü lambda anonim nesne oluşturmaz.
Artılar:
Eksiler: