Just-in-timecompilatie

Just-in-timecompilatie (JIT-compilatie) is een term uit de informatica waarmee een vorm van compilatie wordt bedoeld die plaatsvindt tijdens de uitvoering van een computerprogramma.

Een gewone compiler vertaalt de broncode van een programma in zijn geheel naar machinetaal. Deze machinetaal kan vervolgens uitgevoerd of opgeslagen worden. Een interpreter daarentegen vertaalt de broncode niet naar machinetaal maar voert deze direct uit, of hij vertaalt de broncode naar een tussenvorm die vervolgens uitgevoerd wordt. Beide methodes, compilatie en interpretatie, hebben voordelen.

Bij JIT-compilatie is het doel de voordelen van interpretatie en compilatie te combineren:

  • Gecompileerde programma's zijn snel.
  • Geïnterpreteerde programma's zijn meestal kleiner.
  • Geïnterpreteerde programma's zijn vaak geheel of gedeeltelijk platformonafhankelijk.
  • Tijdens de uitvoering van een programma heeft de interpreter toegang tot runtime-informatie op basis waarvan de uitvoering geoptimaliseerd kan worden: zo besteden veel programma's het grootste deel van de looptijd aan het herhaaldelijk uitvoeren van een klein gedeelte van de code.

JIT-compilatie vindt plaats in de interpreter (ook wel virtuele machine genoemd). De broncode van een programma wordt meestal eerst vertaald naar bytecode door een compiler. Als de interpreter deze bytecode uitvoert en een stuk code (een functie of een methode) tegenkomt dat aan bepaalde voorwaarden voldoet, stopt de interpreter met de uitvoering. Hij compileert het stuk code naar machinetaal en deze machinetaal wordt vervolgens door de CPU uitgevoerd. Als de CPU klaar is gaat de interpreter weer verder. De machinetaal die het resultaat is van de compilatie wordt echter ook opgeslagen. De volgende keer dat dezelfde code uitgevoerd moet worden (denk hierbij aan lussen en functies die vaker worden aangeroepen) hoeft deze niet meer gecompileerd te worden en wordt de bijbehorende machinetaal direct aan de CPU gegeven om uitgevoerd te worden.

Bij JIT-compilatie van een blok code kan de JIT-compiler gebruikmaken van runtime-informatie. Zo kunnen checks voor omstandigheden die op dat moment in het programma nooit voorkomen in de vertaalde machinetaal weggelaten worden. Bij talen met dynamische typering is op het moment van uitvoeren het type van variabelen bekend, iets wat tijdens de "gewone" compilatie niet het geval is. De JIT-compiler kan in zo'n geval code genereren die geoptimaliseerd is voor dat datatype.

Java-programma's worden door een compiler vertaald naar bytecode voor de Java Virtual Machine (JVM). De eerste JVM's voerden deze bytecode uit door middel van interpretatie. Omdat deze methode langzaam was ging men gebruikmaken van JIT-compilatie. Dit leidde tevens tot een hernieuwde en groeiende belangstelling voor JIT-compilatie in het algemeen.

Ook de Common Language Runtime virtuele machine die onderdeel is van Microsofts .NETplatform maakt gebruik van JIT-compilatie.

Verbeteringen

[bewerken | brontekst bewerken]

Bij de eerste keer dat een interpreter met JIT-compiler een bepaald stuk code tegenkomt is er geen snelheidswinst. Sterker nog, omdat de code eerst gecompileerd wordt is er juist een verlies in snelheid. De winst komt pas als de code vaker wordt uitgevoerd.

Dit betekent dat sommige programma's, waarin veel code zit die maar een keer gebruikt wordt, door JIT-compilatie juist langzamer uitgevoerd worden. Een van de methodes die gebruikt wordt om dit te voorkomen is adaptive optimization. Hierbij compileert de interpreter niet direct alle code die hij tegenkomt naar machinetaal: hij interpreteert deze gewoon. Pas als tijdens de uitvoering blijkt dat een bepaald stuk code vaak opnieuw uitgevoerd wordt, wordt deze gecompileerd.

Onder andere Suns HotSpot-implementatie van de JVM maakt gebruikt van adaptive optimization.

Een andere methode om te voorkomen dat de uitvoering van een programma opgehouden wordt door tussentijdse compilatie is het gebruik van meerdere threads. De JIT-compiler draait in dat geval in een eigen thread. Op een computer met meerdere processorkernen kan de JIT-compiler dan synchroon met de interpreter draaien.