Bosh sahifa Wiki Inlining

Inlining

Inlining — compiler function chaqiruvini uning tanasi bilan almashtiradigan optimallashtirishdir. Natijada call va return xarajati kamayishi mumkin, ammo asosiy foyda caller va callee kodi bir joyda ko‘ringach constant propagation, dead code elimination va vectorization kabi keyingi optimallashtirishlarning ochilishidir. inline kalit so‘zi ko‘p tillarda compilerga majburiy buyruq emas, faqat semantik yoki yumshoq ko‘rsatma bo‘lishi mumkin.

Transformatsiya

Quyidagi mantiqiy kodda square kichik function:

int square(int x) { return x * x; }
int area(int n) { return square(n) + 1; }

Inliningdan keyin optimizer area ichida n * n + 1ni ko‘radi. Alohida stack frame va branch yo‘qoladi. Agar argument constant bo‘lsa hisob compile time’da bajarilishi mumkin. Function source’dan yo‘qolishi shart emas; boshqa caller yoki function pointer uchun tashqi nusxa qoladi.

Qaror mezonlari

Compiler callee o‘lchami, call chastotasi, loop ichida ekanligi, recursion va code growthni baholaydi. Kichik hot function yaxshi nomzod. Katta, kam chaqiriladigan error pathni inline qilish instruction cache’ni band qiladi. Profile-guided optimization real call edge chastotasini berib qarorni yaxshilaydi.

Dynamic dispatch’da target compile time’da noma’lum bo‘lishi mumkin. Devirtualization bitta yoki cheklangan targetni isbotlasa inline qiladi. JIT type feedback asosida spekulyativ inline yaratib, guard muvaffaqiyatsiz bo‘lsa generic yo‘lga qaytadi. Megamorphic call site ko‘p targetli bo‘lgani uchun bunday optimallashtirishga yomon nomzod.

Code size va performance

Har call site’ga function tanasini nusxalash binary hajmini oshiradi. Katta code instruction cache miss va page faultni ko‘paytirib, nazariy call tejalishidan ko‘proq zarar berishi mumkin. Compiler inline budget va threshold bilan growthni nazorat qiladi. Size-optimized build tezlik buildidan boshqa qaror chiqaradi.

Inlining call overheadni har doim sezilarli kamaytirmaydi. Zamonaviy CPU call va returnni yaxshi taxmin qiladi, link-time optimizer esa modul chegarasidan o‘tib inline qilishi mumkin. Performance benchmark bilan tasdiqlanadi; source’ga agressiv “force inline” qo‘shishdan oldin profiler bottleneckni ko‘rsatadi.

Semantika va debugging

To‘g‘ri compiler inliningda observable behaviorni saqlaydi. Ammo timing, stack trace va debugger step ko‘rinishi o‘zgaradi. Exception stack’i inline frame metadata yordamida mantiqiy calllarni tiklashi mumkin. Breakpoint optimizer olib tashlagan satrga aniq tushmasligi ehtimoli bor.

C va C++ da inline linkage hamda one-definition qoidalariga ta’sir qiladi. Headerda function definitionini bir nechta translation unit’da berishga ruxsat semantik masala bo‘lib, compiler uni albatta inline qiladi degani emas. Macro’dan farqli ravishda inline function type check, scope va argumentlarning bir marta baholanishini saqlaydi.

Rekursiya va exception yo‘llari

Recursive function cheksiz inline qilinmaydi. Compiler bir yoki bir necha darajani ochishi, keyingi callni oddiy qoldirishi mumkin. Tail-call optimization inliningdan boshqa transformatsiya bo‘lib, ayrim tillarda stack o‘sishini yo‘qotadi. Exception-heavy cold pathni callerga nusxalash hot instruction footprintni kattalashtiradi; compiler uni out-of-line saqlaydi. Inlining synchronization semantikasini ham e’tiborga oladi: synchronized method tanasi ko‘chirilsa lock acquire va release yo‘qolmaydi. Debug yoki instrumentation agent method entryni kuzatsa optimized runtime logical eventni saqlashi yoki optimizationni cheklashi kerak. Shu sababli release va profiling buildlar bir xil qaror bermasligi mumkin.

Bog‘liq tushunchalar

Compiler optimization, Call overhead, Devirtualization, Link-time optimization, Profile-guided optimization, Instruction cache, Macro