inline funksiya — Kotlin mexanizmi bo'lib, funksiya tanasi kompilyatsiya bosqichida to'g'ridan-to'g'ri har bir chaqiruv joyiga joylashtiriladi. Bu lambda parametrlari uchun anonim sinflar va obyektlarni yaratish overhead-ni bartaraf etadi. Kotlin Documentation, 2025 ma'lumotlariga ko'ra, inline kalit so'zi yuqori darajali funksiyalar uchun ayniqsa samarali bo'lib, har bir lambda joylashtirilmasa alohida FunctionN obyektini yaratadi va garbage collector-ni yuklaydi.
Asosiy ma'lumotlar
Inline funksiya — inline kalit so'zi bilan belgilangan funksiya. Kotlin kompilyatori uning uchun chaqiruv bilan alohida bayt-kod yaratmaydi, balki funksiya tanasini to'g'ridan-to'g'ri har bir chaqiruv joyiga nusxalaydi. Asosiy maqsad — lambda ifodalarini qabul qiladigan yuqori darajali funksiyalarni optimallashtirish, chunki har bir lambda odatdagi holatda Function sinfining anonim obyektini yaratadi.
JetBrains Tech Blog (2024) ma'lumotlariga ko'ra, Kotlin-da inline funksiyalardan foydalanish lambdalardan intensiv foydalanadigan funksiyalarda yaratilgan obyektlar sonini 40–60% gacha kamaytirishi mumkin. Sikllarda va yuqori yuklangan operatsiyalarda (saralash, kolleksiyalarni filtrlash) bu o'lchanadigan unumdorlik o'sishini beradi.
Inline bo'lmasa, har bir lambda anonim sinfga (yoki sintez qilingan funksional interfeys instansiyasiga) kompilyatsiya qilinadi. O'zgaruvchilarni tutadigan lambdalar uchun qo'shimcha o'rovchi obyektlar yaratiladi. Inline funksiyalar barcha bu obyektlarni kompilyatsiya bosqichida bartaraf etadi, ularni o'rovchisiz mahalliy o'zgaruvchilarga kirish imkoniyatiga ega to'g'ridan-to'g'ri kod bilan almashtiradi.
Inline-dan faqat lambda parametrlari bo'lgan funksiyalar uchun foydalaning — Kotlin kompilyatori inline foyda keltirmasa, o'zi ogohlantiradi.
Funksiya deklaratsiyasidan oldin inline kalit so'zini qo'shish kifoya. Kompilyator avtomatik ravishda funksiya tanasini chaqiruv joylariga joylashtiradi. Funksiyaning o'zi bayt-kodda to'g'ridan-to'g'ri chaqirilmagan holatlar uchun (masalan, Java kodidan) mavjud bo'lib qoladi.
inline fun Int.repeatAction(action: (Int) -> Unit) {
for (i in 0 until this) {
action(i)
}
}
// Chaqiruv — lambda kodi funksiya tanasiga joylashtiriladi
5.repeatAction { index ->
println("Index: $index")
}
Kompilyatsiyadan so'ng yuqoridagi kod quyidagiga ekvivalent bo'ladi:
// Joylashtirishdan so'ng nima sodir bo'ladi (sxematik):
val $this = 5
for (i in 0 until $this) {
println("Index: $i")
}
Lambda uchun hech qanday obyekt yaratilmaydi — action kodi to'g'ridan-to'g'ri bajariladi. Optimallashtirishning mohiyati aynan shu: Function.invoke() chaqiruvi o'rniga — lambda tanasi bilan kodni to'g'ridan-to'g'ri joylashtirish.
Joylashtirishni tekshirish uchun IntelliJ IDEA-da Tools > Kotlin > Show Kotlin Bytecode ni oching va Decompile tugmasini bosing. Lambda bilan repeatAction chaqiruvi o'rniga for sikli bilan funksiya tanasining to'g'ridan-to'g'ri joylashtirilganini ko'rasiz.
Kotlin-dagi har bir lambda uchta variantdan biriga kompilyatsiya qilinadi. Birinchisi — agar lambda o'zgaruvchilarni tutmasa, u e'lon qilingan sinfning statik metodiga aylanadi. Ikkinchisi — agar bitta o'zgaruvchini tutsa, anonim sinf yaratiladi. Uchinchisi — agar bir nechta o'zgaruvchilarni tutsa, har bir tutilgan o'zgaruvchi uchun maydonlari bo'lgan anonim sinf yaratiladi.
| Lambda turi | Inline bo'lmaganda | Inline bilan |
|---|---|---|
| Tutish yo'q | Bitta statik metod (qayta ishlatiladi) | To'liq joylashtirish, chaqiruvsiz |
| 1 o'zgaruvchini tutish | Anonim sinf (bitta obyekt) | To'liq joylashtirish, obyektsiz |
| N o'zgaruvchini tutish | N maydonli anonim sinf | To'liq joylashtirish, obyektsiz |
| Rekursiv | Oddiy chaqiruv | inline taqiqlangan |
Android Performance Patterns (Google, 2024) ma'lumotlariga ko'ra, kolleksiyalardan intensiv foydalanadigan ilovalarda (filtrlash, saralash, guruhlash) inline funksiyalar ajratmalar sonini 25–35% ga kamaytiradi. Effekt ayniqsa Jetpack Compose-da sezilarli bo'lib, har bir holat o'zgarishi ko'plab lambdalar bilan qayta kompozitsiyaga sabab bo'ladi.
Oddiy funksiyadagi lambda tashqi funksiyadan return qila olmaydi — faqat lambdaning o'zidan lokal return (return@label orqali). Inline funksiyada lambda chaqiruvchi funksiyaning tanasiga joylashtiriladi, shuning uchun nonlocal return mumkin bo'ladi: lambda ichidagi return tashqi funksiyani tugatadi.
inline fun findFirst(
items: List<Int>,
predicate: (Int) -> Boolean
): Int {
for (item in items) {
if (predicate(item)) {
return item
}
}
return -1
}
fun processNumbers() {
val numbers = listOf(1, 2, 3)
val firstEven = findFirst(numbers) { it % 2 == 0 }
// lambdadagi return processNumbers() dan null qaytaradi
}
Nonlocal return muddatidan oldin tugatish uchun qulay, ammo xatolarga olib kelishi mumkin. Agar lambda nolokal kontekstda ishlatilsa (o'zgaruvchiga saqlansa), nonlocal return RuntimeException-ga sabab bo'ladi. Kotlin kompilyatori bunday saqlash urinishida ogohlantiradi.
Funksiya bir nechta lambda parametrlariga ega bo'lganda, ba'zan faqat bir qismini joylashtirish kerak bo'ladi. Buning uchun noinline ishlatiladi — ma'lum lambda parametrini joylashtirishni taqiqlaydi, uni oddiy Function obyekti sifatida qoldiradi.
crossinline modifikatori teskari masalani hal qiladi: lambda joylashtiriladi, lekin nonlocal return taqiqlanadi. Bu lambda boshqa lambda ichida yoki return ruxsat berilmagan kontekstda ishlatilganda kerak (masalan, Runnable-ga uzatilganda).
inline fun processWithCallback(
data: String,
crossinline onSuccess: (String) -> Unit,
noinline onError: (Exception) -> Unit
) {
try {
val result = process(data)
onSuccess(result)
} catch (e: Exception) {
onError(e)
}
}
// noinline: onError o'zgaruvchida saqlanishi yoki boshqa joyga uzatilishi mumkin
val errorHandler = { e: Exception -> log(e.message) }
processWithCallback("input", { println(it) }, errorHandler)
Misolda onSuccess crossinline deb belgilangan — joylashtiriladi, lekin uning ichida return ishlatib bo'lmaydi. onError noinline deb belgilangan — joylashtirilmaydi, uni obyekt sifatida uzatish, sinf maydonida saqlash yoki listener sifatida ishlatish mumkin.
Inline funksiyalarning cheklovlari bor. Rekursiv inline funksiyalar taqiqlangan — kompilyator xato beradi. Inline funksiyalar boshqa modulda e'lon qilingan bo'lsa, private yoki internal ko'rinishga ega bo'la olmaydi, lekin bu cheklov kirish bilan bog'liq, joylashtirish mexanizmi bilan emas.
Bayt-kod hajmi har bir inline funksiya chaqiruvi bilan ortadi, chunki tana nusxalanadi. Kotlin Coding Conventions (JetBrains, 2025) ma'lumotlariga ko'ra, inline-dan faqat 10–15 qatorgacha bo'lgan funksiyalar uchun foydalanish tavsiya etiladi. Katta funksiyalar uchun lambdalarni joylashtirishdan olinadigan foyda APK hajmining oshishi bilan yo'qotilishi mumkin (Android-da bu muhim — 64K metod cheklovi mavjud).
// Tavsiya etilgan amaliyot
inline fun withLock(lock: Lock, action: () -> T): T {
lock.lock()
try {
return action()
} finally {
lock.unlock()
}
}
// Katta funksiyalar uchun tavsiya etilmaydi
inline fun largeComputation(...) { // yomon — tana >50 qator
// 50 qatordan ko'p — oddiy funksiyaga ajratish yaxshiroq
}
Kutubxonalardagi ommaviy inline funksiyalar ehtiyotkorlik talab qiladi: inline funksiya tanasi o'zgarsa, barcha mijozlar qayta kompilyatsiya qilishi kerak. JetBrains modul ichida moslikni saqlash uchun inline funksiyalardan chaqiriladigan a'zolar uchun @PublishedApi internal dan foydalanishni tavsiya qiladi.
Tez-tez so'raladigan savollar
Ha, inline extension funksiya cheklovlarsiz ishlaydi. Masalan: inline fun String.transform(block: (Char) -> Char): String. Kengaytirish joylashtirish qobiliyatiga ta'sir qilmaydi — kompilyator uni oddiy inline funksiya kabi qayta ishlaydi.
Agar funksiya lambda parametrlarini qabul qilmasa — inline ustunlik bermaydi. Kotlin kompilyatori ogohlantiradi: "Expected performance impact from inlining is insignificant. Inlining works best for functions with parameters of functional types." Shuningdek, inline katta funksiyalar uchun bayt-kodning o'sishi tufayli zararlidir.
inline — funksiya tanasini chaqiruv joyiga joylashtiradigan funksiya modifikatori. @JvmInline (value class) — kompilyatsiya vaqtida qiymat bilan almashtiriladigan o'rovchi sinflar uchun mexanizm. Turli tushunchalar: inline chaqiruvlarni optimallashtiradi, value class ma'lumotlarni taqdim etishni optimallashtiradi.
Yo'q, suspend funksiyalar inline bo'la olmaydi, chunki ular Continuation bilan holat mashinasiga kompilyatsiya qilinadi. Biroq, inline funksiya crossinline bilan parametr sifatida suspend lambdani qabul qilishi mumkin. Bu korutinlarda tez-tez ishlatiladi: inline fun launch(block: suspend CoroutineScope.() -> Unit).
Ha, inline funksiyalar disk raskadrovkani qiyinlashtiradi, chunki funksiya tanasi chaqirilmaydi, balki chaqiruv joyiga joylashtiriladi. Stacktrace uzunroq bo'ladi, to'xtash nuqtalari ishlaydi, lekin kutilmagan pozitsiyalarni ko'rsatishi mumkin. JetBrains inlinesiz disk raskadrovka qilishni va uni faqat release yig'ilishlarida yoqishni tavsiya qiladi.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.