Точно навреме обяснена компилация

Точната навреме компилация е метод за подобряване на ефективността на интерпретираните програми. По време на изпълнението програмата може да бъде компилирана в собствен код, за да се подобри нейната производителност. Известен е и като динамична компилация.

Динамичната компилация има някои предимства пред статичната компилация. Когато се изпълняват приложения на Java или C #, средата на изпълнение може да профилира приложението, докато се изпълнява. Това позволява да се генерира по-оптимизиран код. Ако поведението на приложението се промени, докато се изпълнява, средата на изпълнение може да прекомпилира кода.

Някои от недостатъците включват закъснения при стартиране и режийни разходи за компилация по време на изпълнение. За да ограничат режийните, много JIT компилатори компилират само често използваните кодови пътища.

Общ преглед

Традиционно има два метода за конвертиране на изходния код във форма, която може да се изпълни на платформа. Статичната компилация преобразува кода в език за конкретна платформа. Интерпретатор изпълнява директно изходния код.

JIT компилацията се опитва да използва предимствата и на двете. Докато се изпълнява интерпретираната програма, JIT компилаторът определя най-често използвания код и го компилира в машинен код. В зависимост от компилатора, това може да се направи за метод или по-малка част от кода.

Динамичната компилация е описана за първи път в статия на J. McCarthy за LISP през 1960 г.

Just In Time Compilation, JIT или Dynamic Translation, е компилация, която се прави по време на изпълнението на програма. Значение, по време на изпълнение, за разлика от преди изпълнението. Това, което се случва, е преводът в машинен код. Предимствата на JIT се дължат на факта, че тъй като компилацията се извършва по време на изпълнение, JIT компилаторът има достъп до динамична информация по време на изпълнение, което му позволява да прави по-добри оптимизации (като вграждане на функции).

Това, което е важно да се разбере за JIT компилацията, е, че тя ще компилира байт кода в инструкции за машинен код на работещата машина. Това означава, че полученият машинен код е оптимизиран за архитектурата на процесора на работещата машина.

Някои примери за JIT компилатори са JVM (Java Virtual Machine) в Java и CLR (Common Language Runtime), в C #.

История

В началото компилаторът беше отговорен за превръщането на език от високо ниво (дефиниран като по-високо ниво от асемблера) в обектен код (машинни инструкции), който след това ще бъде свързан (чрез линкер) в изпълним файл.

В един момент от еволюцията на езиците компилаторите ще компилират език от високо ниво в псевдокод, който след това ще бъде интерпретиран (от интерпретатор), за да стартира вашата програма. Това елиминира обектния код и изпълними файлове и позволи на тези езици да бъдат преносими към множество операционни системи и хардуерни платформи. Паскал (който се компилира в P-Code) беше един от първите; Java и C # са по-скорошни примери. В крайна сметка терминът P-Code беше заменен с байт код, тъй като повечето псевдооперации са с дължина на байт.

Компилаторът Just-In-Time (JIT) е характеристика на интерпретатора по време на изпълнение, който вместо да интерпретира байт кода при всяко извикване на метод, ще компилира байт кода в инструкциите на машинния код на работещата машина и след това ще извика това вместо това обектен код. В идеалния случай ефективността на стартирания обектен код ще преодолее неефективността на прекомпилирането на програмата всеки път, когато тя се изпълнява.

Типичен сценарий

Изходният код е напълно преобразуван в машинен код

JIT сценарий

Изходният код ще бъде преобразуван в асемблерен език като структура [за бивш IL (междинен език) за C #, ByteCode за java].

Междинният код се преобразува в машинен език само когато приложението се нуждае от необходимите кодове се преобразува само в машинен код.

JIT спрямо Non-JIT сравнение

В JIT не целият код се преобразува в машинен код, първо част от кода, който е необходим, ще се преобразува в машинен код, след това ако извикан метод или функционалност не е в машината, тогава това ще бъде превърнато в машинен код, което намалява тежестта върху процесора. Тъй като машинният код ще бъде генериран по време на изпълнение, JIT компилаторът ще създаде машинен код, който е оптимизиран за стартиране на CPU архитектурата на машината.

Някои примери за JIT са:

  • Java: JVM (Java виртуална машина)
  • C #: CLR (Common Language Runtime)
  • Android: DVM (виртуална машина Dalvik) или ART (Android RunTime) в по-нови версии

Виртуалната машина Java (JVM) изпълнява байт код и поддържа отчитане колко пъти се изпълнява дадена функция. Ако този брой надвиши предварително зададената граница, JIT компилира кода на машинен език, който може да бъде директно изпълнен от процесора (за разлика от нормалния случай, в който javac компилира кода в байт код и след това Java, интерпретаторът интерпретира този байт код ред по ред го преобразува в машинен код и изпълнява).

Също така следващия път, когато тази функция се изчисли, същият компилиран код се изпълнява отново, за разлика от нормалната интерпретация, при която кодът се интерпретира отново ред по ред. Това прави изпълнението по-бързо.