Ішкі кеңейту - Inline expansion

Жылы есептеу, ішкі кеңейту, немесе астарлау, нұсқаулық немесе компиляторды оңтайландыру функцияны ауыстырады сайтты шақыру деп аталатын функцияның денесімен. Кірістірілген кеңейту ұқсас макро кеңейту, бірақ компиляция кезінде бастапқы кодты (мәтінді) өзгертпестен орын алады, ал макро кеңейту компиляцияға дейін пайда болады және әр түрлі мәтінге әкеледі, содан кейін компилятор өңдейді.

Кірістіру маңызды оңтайландыру болып табылады, бірақ өнімділікке күрделі әсер етеді.[1] Сияқты бас бармақ ережесі, кейбір сызықтар кеңістіктің өте аз шығындарымен жылдамдықты жақсартады, бірақ ішкі сызықтар жылдамдыққа зиян тигізеді, себебі сызылған код тым көп жұмсайды нұсқаулық кэші, сондай-ақ айтарлықтай орын қажет. 1980-1990 жылдардағы интервал туралы қарапайым академиялық әдебиеттерге шолу Jones & Marlow 1999-да келтірілген.[2]

Шолу

Кірістірілген кеңейту макро кеңейтуге ұқсас, себебі компилятор функцияның жаңа көшірмесін әр шақырылған жерге орналастырады. Кірістірілген функциялар әдеттегі функциялардан сәл жылдамырақ жұмыс істейді, өйткені функционалды шақыру үстеме ақысы сақталады, бірақ жад жазасы бар. Егер функция 10 рет сызылған болса, онда кодтың ішіне 10 көшірме енгізіледі. Осылайша, жиі шақырылатын кішігірім функциялар үшін сызу жақсы. C ++ тілінде сыныптың мүшелік функциялары, егер класс анықтамасында анықталса, әдепкі бойынша сызылған (пайдаланудың қажеті жоқ кезекте кілт сөз); әйтпесе, кілт сөз қажет. Компилятор бағдарламашының функцияны кірістіру әрекетін елемеуі мүмкін, егер ол әсіресе үлкен болса.

Кірістірілген кеңейту функцияны шақырған кездегі қосымша уақытты (артық уақытты) жою үшін қолданылады. Әдетте бұл жиі орындалатын функциялар үшін қолданылады. Ол сондай-ақ өте кішігірім функциялар үшін кеңістіктік артықшылыққа ие және басқалары үшін түрлендіруге мүмкіндік береді оңтайландыру.

Кірістірілген функцияларсыз құрастырушы қандай функцияларды қатарға қосуға болатындығын шешеді. Бағдарламалаушы қандай функцияларды сызып, қайсысын қосуға болмайтындығын аз бақылайды. Бағдарламалаушыға осы басқару дәрежесін беру қандай функцияларға енетіндігін таңдауда қолданбалы арнайы білімді пайдалануға мүмкіндік береді.

Әдетте, функция шақырылған кезде, бақылау а анықтамасына ауысады филиал немесе нұсқаулыққа қоңырау шалыңыз. Кірістіру кезінде басқару тармаққа немесе қоңырауға нұсқау бермей, функцияның кодына тікелей түседі.

Құрастырушылар әдетте жүзеге асырады мәлімдемелер сызықпен. Цикл шарттары мен цикл денелері қажет жалқау бағалау. Бұл қасиет цикл шарттары мен цикл денелерін есептеуге арналған код сызылған кезде орындалады. Өнімділікті ескеру - бұл мәлімдемелерді енгізудің тағы бір себебі.

Контекстінде функционалды бағдарламалау тілдері, кірістірілген кеңейту әдетте бета-редукция трансформация.

Бағдарламашы функцияны қолмен енгізуі мүмкін бағдарламалауды көшіру және қою, бір реттік операция ретінде бастапқы код. Сонымен қатар, сызуды бақылаудың басқа әдістері жақсы (төменде қараңыз), өйткені олар бағдарламалаушы бастапқы функция корпусының қайталанған (мүмкін өзгертілген) нұсқасын қараған кезде туындайтын қателерді азайтпайды, ал сызылған функциядағы қатені түзетеді.

Өнімділікке әсері

Бұл оңтайландырудың тікелей әсері кеңістікті пайдалануды нашарлату есебінен уақыттың өнімділігін жақсарту (қосымша шығындарды жою арқылы) болып табылады.[a] (байланысты қайталау дене функциясы). Функция денесінің қайталануына байланысты кодтың кеңеюі қарапайым жағдайларды қоспағанда,[b] осылайша кірістірілген кеңеюдің тікелей әсері уақытты кеңістіктің есебінен жақсарту болып табылады.

Алайда, ішкі кеңейтудің негізгі артықшылығы - бұл функция корпусының көлемін ұлғайтуға байланысты одан әрі оңтайландыруға және жоспарлауды жақсартуға мүмкіндік беру, өйткені үлкен функцияларда оңтайландыру мүмкін.[3] Кірістірілген кеңеюдің жылдамдыққа әсері күрделі, себебі жад жүйесінің жұмысына көп әсер етеді (бірінші кезекте) нұсқаулық кэші ), ол қазіргі заманғы процессорлардағы өнімділікті басым етеді: белгілі бір бағдарламаға және кэшке байланысты, белгілі бір функциялардың өнімділігі жоғарылауы немесе төмендеуі мүмкін.[1]

Инлизингтің әсері әр түрлі абстракция деңгейіне байланысты бағдарламалау тілі мен бағдарламасына байланысты өзгеріп отырады. C және Fortran сияқты төменгі деңгейдегі императивті тілдерде бұл көбінесе жылдамдықтың 10-20% жоғарылауы болып табылады, бұл код өлшеміне аз әсер етеді, ал абстрактілі тілдерде бұл едәуір маңызды болуы мүмкін, өйткені сызылған қабаттардың саны, экстремалды мысалмен Өзіндік, мұнда бір компилятор 4-тен 55-ке дейін жақсарту коэффициенттерін сызу арқылы көрді.[2]

Функционалды шақыруды жоюдың тікелей артықшылықтары:

Инлингтің басты артықшылығы - бұл одан әрі оңтайландыру. Функциялардың шекараларын кесіп өтетін оңтайландыруларды талап етпестен жасауға болады процедуралық оңтайландыру (IPO): сызу орындалғаннан кейін қосымша ішкікеңейтілген функционалды денеде процедуралық оңтайландыру («жаһандық оңтайландыру») мүмкін болады. Мысалға:

  • A тұрақты аргумент ретінде сәйкес келетін параметрдің барлық даналарына көбіне таралуы мүмкін немесе функцияның бір бөлігі циклден «шығарылып» алынуы мүмкін (арқылы кодтың инвариантты қозғалысы ).
  • Тіркеуді бөлу үлкен функция денесі бойынша жасалуы мүмкін.
  • Сияқты жоғары деңгейлі оңтайландыру қашу талдауы және құйрықты қайталау, үлкен көлемде орындалуы және тиімді болуы мүмкін, әсіресе, егер осы оңтайландыруларды жүзеге асыратын компилятор бірінші кезекте ішкі процедуралық талдауға сүйенетін болса.[4]

Мұны сызусыз жасауға болады, бірақ айтарлықтай күрделі компилятор мен байланыстырғышты қажет етеді (қоңырау шалушы мен қоңырау шалушы жеке компиляцияда болған жағдайда).

Керісінше, кейбір жағдайларда тілдің спецификациясы кейбір оңтайландыруларға жол бермей, рәсімге сызба енгізілгеннен кейін енді жасай алмайтын процедураларға аргументтер туралы қосымша болжамдар жасауға мүмкіндік беруі мүмкін. Ақылды компиляторлар (мысалы Glasgow Haskell құрастырушысы ) осыны қадағалайтын болады, бірақ аңғал аңдатпа бұл ақпаратты жоғалтады.

Есте сақтау жүйесіне кірудің келесі артықшылығы:

  • Бөлшектерді жою және жадыда бірге орындалатын кодты сақтау нұсқаулық кэшінің жұмысын жақсарту арқылы жақсартады анықтама орны (нұсқаулардың кеңістіктік локальдылығы мен реттілігі). Бұл жүйелілікке бағытталған оңтайландырулардан аз, бірақ маңызды.[5]

Кірістірудің тікелей құны әр қоңырау сайтында функционалды дененің көшірмеленуіне байланысты код өлшемін ұлғайтады. Алайда, ол әрдайым мұны жасай бермейді, яғни өте қысқа функциялар кезінде, егер бұл функция денесі функционалдық шақырудың өлшемінен кіші болса (қоңырау шалушыда, оның ішінде тривиальды және қайтарылатын мәнмен жұмыс жасау). қол жетімді әдістер немесе мутациялық әдістер (гетердер мен сеттерлер); немесе тек бір жерде қолданылатын функция үшін, бұл жағдайда ол қайталанбайды. Осылайша, егер көбіне жиі кездесетін болса, код өлшемін оңтайландыру кезінде сызықты азайту немесе жою мүмкін ендірілген жүйелер.

Инлайндау сонымен қатар команданың кэш өнімділігіне зиян келтіретін кодтың кеңеюіне байланысты (қайталануына байланысты) өнімділікке шығындар әкеледі.[6] Бұл, егер кеңейтуге дейін, егер маңызды болса жұмыс жиынтығы бағдарламаның (немесе кодтың ыстық бөлімі) жад иерархиясының бір деңгейіне сәйкес келеді (мысалы, L1 кэш ), бірақ кеңеюден кейін ол енді сәйкес келмейді, соның салдарынан кэштің жиі жіберілуіне әкеледі. Иерархияның әртүрлі деңгейлеріндегі өнімділіктің айтарлықтай айырмашылығына байланысты, бұл өнімділікке айтарлықтай зиян тигізеді. Ең жоғары деңгейде бұл жоғарылауға әкелуі мүмкін бет ақаулары, байланысты апаттық өнімділіктің нашарлауы ұру немесе бағдарлама мүлдем жұмыс істемейді. Бұл соңғы жұмыс үстеліндегі және серверлік қосымшаларда сирек кездеседі, мұнда код мөлшері қол жетімді жадына қатысты аз, бірақ ендірілген жүйелер сияқты ресурстармен шектелетін орта үшін мәселе болуы мүмкін. Бұл мәселені жеңілдетудің бір жолы - функцияларды кішігірім ыстық жолға бөлу (жылдам жол ) және үлкен суық кірмейтін жол (баяу жол).[6]

Ішкі жағу өнімділігі, ең алдымен, көптеген жерлерде қолданылатын үлкен функциялар үшін проблема болып табылады, бірақ сызықтық өнімділігін төмендететін шығынсыздық нүктесін анықтау қиын және нақты жүктеуге тәуелді, сондықтан ол қолмен оңтайландыруға немесе профильді басқаратын оңтайландыру.[7] Бұл басқа кодты кеңейтетін оңтайландыруларға ұқсас мәселе циклды босату, бұл сонымен қатар өңделген нұсқаулардың санын азайтады, бірақ нашар жұмыс істеуіне байланысты өнімділікті төмендетуі мүмкін.

Кэштің жұмысына сызудың нақты әсері күрделі. Кэштің кішігірім өлшемдері үшін (кеңейтуге дейінгі жұмыс жиынтығынан әлдеқайда аз) көбейтілген дәйектілік басым болады, ал ішіне енгізу кэш өнімділігін жақсартады. Кэштің жұмыс жиынтығына жақын өлшемдері үшін, онда инлинг жұмыс жинағы кэшке сыймайтындай етіп кеңейеді, бұл басым болады және кэш өнімділігі төмендейді. Кэштің жұмыс жиынтығынан үлкен өлшемдері үшін сызу кэштің жұмысына айтарлықтай әсер етпейді. Сонымен қатар, кэш дизайнындағы өзгерістер, мысалы жүкті бағыттау, кэшті жіберіп алудың артуын өтей алады.[8]

Компиляторды қолдау

Компиляторлар қандай функционалдық қоңырауларға кіру керектігін шешу үшін әртүрлі механизмдерді қолданады; бұған бағдарламашылардың белгілі бір функцияларға арналған нұсқаулықтары, жалпы басқару арқылы қоса берілуі мүмкін командалық жолдың параметрлері. Кірістіру пайдалы деген пікірге сүйене отырып, көптеген тілдердегі көптеген құрастырушылар автоматты түрде жасайды, ал басқа жағдайларда оны компилятор арқылы қолмен көрсетуге болады директивалар, әдетте кілт сөзін немесе құрастырушы директивасы деп аталады кезекте. Әдетте, бұл тек тілді және компиляторға байланысты әр түрлі болатын кеңістікті қажет етпейтін, керісінше қажет деген нұсқаулар.

Әдетте, компилятор әзірлеушілер жоғарыдағы мәселелерді есте сақтайды және енгізеді эвристика көптеген жағдайларда өнімділікті нашарлатпай, жақсарту үшін қандай функцияларды ішке қосуды таңдайтын компиляторларға.

Іске асыру

Бір рет құрастырушы нақты функцияның ішіне кіруге шешім қабылдады, ішінара операцияны өзі орындау қарапайым. Компилятор әр түрлі тілдердегі кодтар бойынша функцияларды енгізетіндігіне байланысты, компилятор жоғары деңгейдің бірінде де инлинг жасай алады аралық өкілдік (сияқты синтаксистік ағаштар ) немесе төменгі деңгейдегі аралық ұсыныс. Екі жағдайда да компилятор жай есептейді дәлелдер, оларды функция аргументтеріне сәйкес келетін айнымалыларда сақтайды, содан кейін функция денесін шақыру сайтына кірістіреді.

Байланыстырушылар сонымен қатар функцияны сызып орындай алады. Байланыстырушы функцияларды енгізген кезде, кітапхана функциялары сияқты қайнар көзі жоқ функцияларды енгізуі мүмкін (қараңыз) уақытты оңтайландыру ). A жұмыс уақыты жүйесі сонымен қатар функцияны енгізе алады. Жұмыс уақыты кірістіру динамикалық профильді ақпаратты пайдалана отырып, қандай функцияларға кіретіндігі туралы жақсы шешім қабылдау үшін қолдана алады Java Hotspot компиляторы.[9]

Мұндағы бастапқы деңгейде «қолмен» орындалатын кірістірілген кеңейтудің қарапайым мысалы C бағдарламалау тілі:

int алдын-ала(int х){    егер (х == 0)        қайту 0;    басқа        қайту х - 1;}

Түстен бұрын:

int функциясы(int ж) {    қайту алдын-ала(ж) + алдын-ала(0) + алдын-ала(ж+1);}

Кесілгеннен кейін:

int функциясы(int ж) {    int тм;    егер (ж   == 0) тм  = 0; басқа тм  = ж - 1;       /* (1) */    егер (0   == 0) тм += 0; басқа тм += 0 - 1;       /* (2) */    егер (ж+1 == 0) тм += 0; басқа тм += (ж + 1) - 1; /* (3) */    қайту тм;}

Бұл тек мысал екенін ескеріңіз. С нақты қосымшасында, мысалы, кірістірілген тілдік мүмкіндікті қолданған жөн болар еді параметрленген макростар немесе кірістірілген функциялар компиляторға кодты осылай түрлендіру керектігін айту. Келесі бөлімде осы кодты оңтайландыру жолдары келтірілген.

Құрастыру макросын кеңейту арқылы

Ассемблер макросы нұсқаулар тізбегін әдетте макро кеңейту жолымен бір макро дерек көзінен (нөлдік немесе одан да көп параметрлермен) макро кеңейту жолымен жасауға болатын кірістірудің баламалы тәсілін ұсыну. Параметрлердің бірі балама түрде бір реттік бөлек шығарудың нұсқасы болуы мүмкін ішкі программа тізбекті қамтиды және оның орнына функцияға сызылған қоңырау арқылы өңделеді.

MOVE FROM = массив1, TO = массив2, INLINE = ЖОҚ

Эвристика

Кірістіру үшін әр түрлі эвристиканың зерттелді. Әдетте, сызылған алгоритмде белгілі бір код бюджеті болады (бағдарлама көлемінің рұқсат етілген ұлғаюы) және осы бюджеттен асып кетпестен ең құнды қоңыраулар тізімін жасауға бағытталған. Осы мағынада, көптеген сызылған алгоритмдер әдетте моделденеді Рюкзак мәселесі.[10] Қоңырау шалушылардың қайсысы құнды екенін анықтау үшін, сызылған алгоритм олардың пайдасын бағалауы керек, яғни. орындалу уақытының күтілетін төмендеуі. Әдетте, кірушілер пайдасын бағалау үшін әртүрлі кодтық жолдардың орындалу жиілігі туралы профильдік ақпаратты пайдаланады.[11]

Профиль жасаудан басқа, жаңа дәл уақытында құрастырушылар тағы бірнеше озық эвристиканы қолданыңыз, мысалы:[4]

  • Қандай кодтық жолдардың орындалу уақытын ең жақсы қысқартуға әкелетінін нақтылау (кірістіру нәтижесінде компилятордың қосымша оңтайландыруын қосу арқылы) және мұндай жолдардың пайдасын арттыру.
  • Компиляция бірлігінің өлшеміне және қазірдің өзінде сызылған кодтың мөлшеріне сүйене отырып, шығындар үшін пайда шегін бейімдеп реттеу.
  • Ішкі бағдарламаларды кластерлерге топтастыру және сингулярлық ішкі бағдарламалардың орнына тұтас кластерлерді сызу. Мұнда эвристикалық әдістер кластерді тек дұрыс ішкі жиынтығына кірістіру ештеңені қоспай қарағанда нашар өнімділікке әкелетін әдістерді топтастыру арқылы болжайды.

Артықшылықтары

Кірістірілген кеңейтудің өзі оңтайландыру болып табылады, өйткені ол қоңыраулардың үстеме ақысын жояды, бірақ бұл әлдеқайда маңызды түрлендіруге мүмкіндік береді. Яғни, компилятор функционалды денені өзінің шақыру сайтының контекстінде кеңейткеннен кейін - көбінесе түзетілуі мүмкін аргументтермен тұрақтылар - ол бұрын мүмкін емес болған түрлендірулерді жасай алады. Мысалы, а шартты тармақ осы нақты сайтта әрдайым шын немесе жалған болып шығуы мүмкін. Бұл өз кезегінде қосылуы мүмкін өлі кодты жою, кодтың инвариантты қозғалысы, немесе индукциялық айнымалы жою.

Алдыңғы бөлімдегі С мысалында оңтайландыру мүмкіндіктері мол. Компилятор келесі қадамдар тізбегін орындай алады:

  • The tmp + = 0 (2) және (3) белгіленген жолдардағы тұжырымдар ештеңе жасамайды. Компилятор оларды алып тастай алады.
  • Шарт 0 == 0 әрқашан дұрыс, сондықтан компилятор (2) жолды нәтижесімен ауыстыра алады, tmp + = 0 (бұл ештеңе жасамайды).
  • Компилятор шартты қайта жаза алады y + 1 == 0 дейін у == -1.
  • Компилятор өрнекті азайта алады (y + 1) - 1 дейін ж.
  • Өрнектер ж және y + 1 екеуі де нөлге тең бола алмайды. Бұл компиляторға бір сынақты жоюға мүмкіндік береді.
  • Сияқты мәлімдемелерде егер (y == 0) y қайтарады мәні ж денеде белгілі, және астын сызуға болады.

Жаңа функция келесідей көрінеді:

int функциясы(int ж) {    егер (ж == 0)        қайту 0;    егер (ж == -1)        қайту -2;    қайту 2*ж - 1;}

Шектеулер

Кірістірілген толық кеңейту әрдайым мүмкін емес, себебі рекурсия: рекурсивті кірістірілген қоңыраулар тоқтатылмайды. Шектелген көлемді кеңейту немесе талдау сияқты әр түрлі шешімдер бар шақыру графигі және белгілі бір түйіндердегі ілмектерді бұзу (яғни, рекурсивті циклда кейбір шетін кеңейтпеу).[12] Макро кеңейтуде бірдей проблема туындайды, өйткені рекурсивті кеңейту аяқталмайды және әдетте рекурсивті макростарға тыйым салу арқылы шешіледі (C және C ++ сияқты).

Макростармен салыстыру

Сияқты тілдерде дәстүрлі түрде C, кірістірілген кеңейту дереккөз деңгейінде жүзеге асырылды параметрленген макростар. Кірістірілген нақты функцияларды пайдалану C99, осы тәсілге қарағанда бірнеше артықшылықтар береді:

  • C тілінде макро шақырулар орындалмайды типті тексеру немесе тіпті аргументтердің дұрыс қалыптасқанын тексеріңіз, ал функционалдық қоңыраулар әдетте жасайды.
  • С-де макро функция функциясы сияқты мағынасы бар return кілт сөзін қолдана алмайды (кеңейтуді сұраған функцияны макростан гөрі аяқтайды). Басқаша айтқанда, макро оның ішіндегі соңғы өрнектің нәтижесі болып табылмайтын нәрсені қайтара алмайды.
  • С макросы тек мәтіндік алмастыруды қолданатындықтан, бұл аргументтерді қайта бағалау салдарынан күтпеген жанама әсерлер мен нәтижесіздікке әкелуі мүмкін операциялардың тәртібі.
  • Макростардағы компилятор қателерін түсіну қиын, себебі олар бағдарламашы терген кодқа емес, кеңейтілген кодқа сілтеме жасайды. Осылайша, макро-кеңейтілген кодқа қарағанда, сызылған код бойынша ақпаратты жөндеу өте пайдалы.
  • Көптеген конструкцияларды ыңғайсыз немесе макростар арқылы өрнектеу мүмкін емес, немесе айтарлықтай өзгеше синтаксисті қолданады. Кірістірілген функциялар кәдімгі функциялармен бірдей синтаксисті қолданады және оларды өз қалауынша сызықтық және сызықтықсыз қоюға болады.

Көптеген компиляторлар кейбірін кеңейте алады рекурсивті функциялар;[13] рекурсивті макростар әдетте заңсыз болып табылады.

Bjarne Stroustrup, C ++ дизайнері макростардан мүмкіндігінше аулақ болу керек екенін баса айтқысы келеді және кірістірілген функцияларды кеңінен қолдайды.

Іріктеу әдістері

Көптеген компиляторлар қай жерде пайдалы болса да, агрессивті түрде кірістіреді. Бұл үлкенге әкелуі мүмкін орындалатын файлдар, жад сыйымдылығы процессордың жылдамдығынан гөрі жылдам өскендіктен, агрессивті сызу барған сайын жақсырақ бола бастады. Кірістіру - бұл маңызды оңтайландыру функционалды тілдер және объектіге бағытталған бағдарламалау тілдері классикалық оңтайландыруларды тиімді ету үшін, әдетте, олардың кішігірім функциялары үшін жеткілікті контекстті қамтамасыз етеді.

Тілдерді қолдау

Көптеген тілдер, соның ішінде Java және функционалды тілдер, кірістірілген функциялар үшін тілдік конструкцияларды ұсынбайды, бірақ олардың компиляторлары немесе аудармашылары көбінесе агрессивті кірістірілген кеңейтуді орындайды.[4] Басқа тілдер нақты кеңестерге, әдетте, компилятор ретінде құрылымдар ұсынады директивалар (прагмалар).

Ішінде Ada бағдарламалау тілі, кірістірілген функцияларға арналған прагма бар.

Функциялары Жалпы Лисп ішіндегі ретінде анықталуы мүмкін кезекте мынадай декларация:[14]

 (декларация (кезекте жөнелту)) (бас тарту жөнелту (х)   (функционалды     (алу (автомобиль х) жіберу) х))

The Хаскелл құрастырушы ЖЖ функцияларды немесе мәндерді жеткілікті кіші етіп енгізуге тырысады, бірақ тілдік прагманы қолдану арқылы анықтауға болады:[15]

кілт_функциясы :: Int -> Жол -> (Bool, Қосарланған){- # INLINE кілт_функциясы # -}

C және C ++

C және C ++ бар кезекте кілт сөз, ол компилятордың директивасы ретінде де жұмыс істейді, ол кірістіру екенін көрсетеді қалаған бірақ жоқ қажет- сонымен қатар көріну мен байланыстырушы мінез-құлықты өзгертеді. Көрнекіліктің өзгеруі функцияны стандартты С құралдар тақтасы арқылы сызуға мүмкіндік беру үшін қажет, мұнда жеке файлдар жинақталады (керісінше, аударма бірліктері ) сілтемемен жалғасады: байланыстырушы функцияларды кірістіре алуы үшін, олар тақырыпта көрсетілуі керек (көрінуі керек) кезекте (көптеген анықтамалардан түсініксіздікті болдырмау үшін).

Сондай-ақ қараңыз

Ескертулер

  1. ^ Кеңістікті пайдалану «нұсқаулардың саны» болып табылады және жұмыс уақытының кеңістігін пайдалану болып табылады екілік файл өлшемі.
  2. ^ Код өлшемі іс жүзінде өте қысқа функциялар үшін кішірейеді, мұнда қоңырау шығыстары функцияның денесінен үлкен болады немесе қайталану пайда болмайтын бір реттік функциялар.

Пайдаланылған әдебиеттер

  1. ^ а б Чен және басқалар. 1993 ж.
  2. ^ Чен және басқалар. 1993 ж, 3.4 Функцияның ішкі кеңеюі, б. 14.
  3. ^ а б c [1] Prokopec және басқалар, дәл уақыттағы компиляторлар үшін оңтайландыруға негізделген көбейтілген ішкі ауыстыру алгоритмі, JGOM үшін Graal компиляторында қолданылған инлайнер туралы CGO'19 басылымы.
  4. ^ Чен және басқалар. 1993 ж, 3.4 Функцияның ішкі кеңеюі, б. 19-20.
  5. ^ а б Бенджамин Пулейн (8 тамыз, 2013). «Ерекше жылдамдықты арттыру: өлшем маңызды».
  6. ^ Мысалға қараңыз Адаптивті оңтайландыру жүйесі Мұрағатталды 2011-08-09 сағ Wayback Machine ішінде Джикес RVM Java үшін.
  7. ^ Чен және басқалар. 1993 ж, 3.4 Функцияның ішкі кеңеюі, б. 24–26.
  8. ^ [2] Java-ға арналған Graal JIT компиляторында қолданылатын инлайнердің сипаттамасы
  9. ^ [3] Шейфлер, құрылымдалған бағдарламалау тіліне кірістірілген ауыстыруды талдау
  10. ^ [4] Мэттью Арнольд, Стивен Финк, Вивек Саркар және Питер Свини, Инлинг үшін статикалық және профильді эвристиканы салыстырмалы зерттеу
  11. ^ Джонс және Марлоу 1999, 4. Аяқтауды қамтамасыз ету, 6–9 бб.
  12. ^ Рекурсивті болып табылатын ішкі бағдарламаларға арналған семантика «бойынша Генри Дж. Бейкер
  13. ^ Декларация КЕЗЕКТЕ, ЕСКЕРТУ кезінде Жалпы Lisp HyperSpec
  14. ^ 7.13.5.1. INLINE прагма GHC тіл ерекшеліктері

Сыртқы сілтемелер