Interpret (software)
Interpret je v informatice speciální počítačový program, který umožňuje přímo vykonávat (interpretovat) zápis jiného programu v jeho zdrojovém kódu ve zvoleném programovacím jazyce. Program proto není nutné převádět do strojového kódu cílového procesoru, jako je tomu v případě překladače. Interpret tak umožňuje programování kódu, který je snadno přenositelný mezi různými počítačovými platformami. Interpret je použit též pro shell, který vytváří příkazový řádek.
Rozdíl mezi interpretem a kompilátorem můžeme vztáhnout též na programovací jazyky, které podle toho můžeme rozdělit na interpretované a kompilované. Teoreticky je možné pro jakýkoliv programovací jazyk naprogramovat jak interpret, tak kompilátor, avšak interpretované jsou obvykle vyšší programovací jazyky.
Typy interpretů
Interprety se mohou chovat třemi různými způsoby podle toho, jak zpracovávají zdrojový kód programu:
- provádějí přímo zdrojový kód
- přeloží zdrojový kód do efektivnějšího mezikódu, který následně spustí
- přímo spustí předem vytvořený předkompilovaný mezikód[1], který je produktem části interpretu
Perl, Python nebo MATLAB jsou interprety 2. typu. UCSD Pascal a Java jsou 3. typu (zdrojové kódy jsou kompilovány předem, uloženy ve strojově nezávislém tvaru, který je po spuštění linkován a interpretován nebo kompilován v případě použití JIT). Některé programovací jazyky (například Smalltalk nebo Python) mohou kombinovat 2. a 3. typ. Příkladem interpretů 1. typu je unixový shell, COMMAND.COM nebo interprety jazyka BASIC.
Výhody interpretace
Interpretace kódu má proti překladu do strojového kódu a přímému spuštění některé výhody:
- Rychlost vývoje – zejména u větších projektů je při interpretaci rychlejší cyklus editace – spuštění – oprava chyb.
- Laditelnost – stav interpretu je jednoznačně definován, jeho činnost přesně odpovídá zdrojovému kódu (nebývají použity optimalizace, které mohou původní strukturu kódu zakrýt nebo pozměnit).
- Kompatibilita – stejný program může být bez problémů spuštěn na mnoha cílových architekturách, jazyk obvykle zakrývá rozdíly mezi různými operačními systémy.
- Správa paměti – při běhu interpretovaného programu nemusí být proměnné vázány na fyzickou adresu v operační paměti, proto je možné přemapování proměnných, což může zabránit fragmentaci paměti.
- Jednoduchost – obecně je mnohem snadnější vytvořit interpret jazyka, než kompilátor; interpretace značně zjednodušuje vytváření aplikačních nebo experimentálních jazyků, přičemž jednoduchost vytváření a modifikace interpretů na druhou stranu může vést k problémům s kompatibilitou.
Efektivita
Hlavní nevýhodou interpretu je, že v případě, kdy je program interpretován, zpravidla probíhá pomaleji, než když je kompilován. Rozdíl v rychlosti závisí na velikosti programu. Obvykle trvá déle spouštět program přes interpret než spouštět kompilovaný kód, ale může trvat kratší dobu, než je celková doba potřebná ke kompilaci a spuštění. To je důležité zejména při prototypování a testování kódu, při cyklu editace–interpretace–ladění může být často mnohem kratší, než je cyklus editace – kompilace – spuštění – ladění.
Interpretovaný kód je pomalejší než běh kompilovaného kódu, protože interpret musí analyzovat každý program při každém spuštění a pak provést požadovanou akci, vzhledem k tomu, že kompilovaný kód právě provádí akci ve stanovené souvislosti určené na základě kompilace. Tato run-time analýza je známá jako „interpretační režie“. Přístup k proměnné je také pomalejší, protože v interpretu musí být provedeno mapování identifikátorů na paměťová místa opakovaně za běhu (kompilovaný kód přistupuje k proměnným přímo na cílovou adresu bez nutnosti vyhledávání).
Existují různé kompromisy mezi rychlostí vývoje při použití interpretu a rychlostí provedení programu při použití kompilátoru. Některé jazyky (např. Lisp) umožňují interpretovaný a kompilovaný kód volat navzájem a sdílet proměnné. To znamená, že jednou je program testován a odladěn pod interpretem, lze jej kompilovat a tím využívat rychlejšího provedení programu, zatímco je program vyvíjen. Mnohé interprety nebudou vykonávat zdrojový kód tak, jak je napsán, ale převedou si jej do nějaké kompaktnější vnitřní formy. Například některé interprety BASICu nahradí klíčová slova jednobytovým znakem, který lze použít k nalezení instrukce ve skoku v tabulce. Interpret může používat stejný lexikální a syntaktický analyzátor jako kompilátor a pak interpretovat výsledný abstraktní syntaktický strom.
Interpret bytekódu
Existuje celé spektrum možností mezi interpretací a kompilací, v závislosti na úrovni analýzy provedené před spuštěním programu. Například Emacs Lisp je kompilován do bytekódu, který je vysoce komprimovaná a optimalizovaná reprezentace zdrojového kódu v Lispu, ale není to strojový kód (a tedy není vázán na žádný konkrétní hardware). Tento „kompilovaný“ kód je pak interpretován v bytekódu interpreta (sám je napsán v jazyce C). Kompilovaný kód je v tomto případě strojový kód pro virtuální stroj, který není realizován pro hardware, ale jako interpret bytekódu. Stejný přístup se používá ve Forth kódu používaném systémy Open Firmware: zdrojový jazyk je kompilován do „F kódu“ (bytekód), který je pak interpretován virtuálním strojem.
Interpret abstraktního syntaktického stromu
Mimo možnosti interpretace a kompilace lze využít i jiný přístup, a to transformace zdrojového kódu do optimálního abstraktního syntaktického stromu (abstract syntax tree – AST), a následné řízení výkonu programu podle této struktury. V tomto přístupu je třeba analyzovat každou větu pouze jednou. Hlavní výhodu oproti bytekódové interpretaci je, že AST udržuje globální program, strukturu a vztahy mezi instrukcemi (které se v bytekódové reprezentaci ztrácí) a poskytuje kompaktnější reprezentaci.
Proto byl navržen AST jako lepší průběžný formát pro just-in-time kompilátory než bytekód. Rovněž umožňuje provádět lepší analýzu za běhu. Na interpretu Javy založeném na AST bylo dokázáno, že je rychlejší než obdobné interprety bytekódu, díky této silnější optimalizaci dovoluje mít kompletní strukturu programu, která je k dispozici již v průběhu spuštění.
Kompilace just-in-time
Další možností, která využívá výhod interpretů, bytekódových interpretů a kompilací, je kompilace just-in-time (JIT, anglicky právě včas), což je technika, ve které je meziprodukt reprezentace programu kompilován do nativního strojového kódu za běhu. To vyrovnává účinnost běhu nativního kódu, vzhledem k nárokům na čas spuštění a paměť, pokud je bytekód nebo AST nejprve kompilován. Adaptivní optimalizace je doplňkovou technikou, ve které interpret profiluje běžící program a sestavuje své nejčastěji kompilované části do nativního kódu. Obě techniky jsou několik desítek let staré, byly uvedeny již v jazyce Smalltalk (1980).
Kompilace just-in-time získala větší pozornost mezi implementátory jazyků v posledních letech. Například jazyky Java, Python a .NET Framework nyní všechny obsahují JIT.
Historie
Termín „interpret“ měl trochu jiný význam u elektromechanických výpočetních strojů, které se používaly před příchodem elektronických strojů po roce 1940. V té době se prováděly sofistikované výpočty nad velkým množstvím dat (například sčítání lidu v USA v roce 1890) s pomocí děrných štítků, které se ručně předávaly podle naplánovaného procesu mezi různými specializovanými stroji. Převod z děrných štítků do čitelné podoby zajišťovaly například stroje Numerický interpret IBM 550 (anglicky Numeric Interpreter, rok 1930) a Znakový interpret IBM 557 (anglicky Alphabetic Interpreter, rok 1954).
První elektronické počítače (tzv. mainframe) měly velmi malý výpočetní výkon, málo paměti a velmi jednoduché operační systémy s dávkovým zpracováním úloh, takže bylo nemožné mít v paměti počítače zároveň interpret a prováděný program a využívat multitasking. Proto se v té době používaly kompilátory a kompilované programovací jazyky, kdy bylo možné v prvním kroku nejprve ze zdrojového kódu vytvořit spustitelný program ve strojovém kódu a ten teprve pak samostatně spustit a vykonat. Přesto obsahovaly tyto první počítače interprety skriptovacích jazyků, které interpretovaly a řídily zpracování dávkových úloh (například Job Control Language, DIGITAL Command Language). Vzhledem k výkonu tehdejších počítačů ale byl zápis dávek poměrně obtížný a komplikovaný, protože se kladl důraz na snadnou a rychlou interpretaci zápisu počítačem a ne na pohodlí uživatele.
Reference
- V tomto významu je procesor také interpretem strojových instrukcí