Języki skompilowane a interpretowane


284

Próbuję lepiej zrozumieć różnicę. Znalazłem wiele wyjaśnień w Internecie, ale mają one raczej charakter abstrakcyjny, a nie praktyczne.

Większość moich doświadczeń programistycznych dotyczy CPython (dynamiczny, interpretowany) i Java (statyczny, skompilowany). Rozumiem jednak, że istnieją inne rodzaje tłumaczonych i kompilowanych języków. Oprócz faktu, że pliki wykonywalne mogą być dystrybuowane z programów napisanych w skompilowanych językach, czy są jakieś zalety / wady każdego typu? Często słyszę ludzi, którzy twierdzą, że z tłumaczonych języków można korzystać interaktywnie, ale wierzę, że języki skompilowane mogą mieć również implementacje interaktywne, prawda?


32
Wybrałeś dokładnie najgorsze języki do tego porównania. Oba są skompilowane bajtowo. Jedyną prawdziwą różnicą między nimi jest JITer, a nawet Python ma częściową (psyco).
Ignacio Vazquez-Abrams

1
Dobrym przykładem interaktywnego języka kompilowanego jest Clojure - wszystko jest w pełni skompilowane (najpierw do JVM, a następnie do kodu natywnego za pośrednictwem JIT). Jednak duża część rekompilacji przebiega dynamicznie, a rozwój odbywa się często w interaktywnej powłoce REPL, w której można ocenić dowolną funkcję w uruchomionym środowisku.
mikera

Standard ML to kolejny interaktywny język kompilowany; wbudowany kompilator wydaje również prawdziwy natywny kod maszynowy.
Donal Fellows


Odpowiedzi:


459

Skompilowany język to taki, w którym program po skompilowaniu jest wyrażany w instrukcjach maszyny docelowej. Na przykład operacja dodawania „+” w kodzie źródłowym może zostać przetłumaczona bezpośrednio na instrukcję „ADD” w kodzie maszynowym.

Językiem interpretowanym jest język, w którym instrukcje nie są wykonywane bezpośrednio przez maszynę docelową, lecz zamiast tego odczytywane i wykonywane przez inny program (który zwykle jest napisany w języku maszyny rodzimej). Na przykład ta sama operacja „+” byłaby rozpoznawana przez interpretera w czasie wykonywania, który wówczas wywoływałby własną funkcję „add (a, b)” z odpowiednimi argumentami, która następnie wykonałaby instrukcję maszynową „ADD” .

Możesz zrobić wszystko, co możesz zrobić w języku interpretowanym w języku kompilowanym i odwrotnie - oba są kompletne w Turingu. Oba mają jednak zalety i wady w zakresie implementacji i użytkowania.

Zamierzam całkowicie uogólnić (puryści wybaczają mi!), Ale z grubsza, oto zalety skompilowanych języków:

  • Szybsza wydajność dzięki bezpośredniemu użyciu natywnego kodu komputera docelowego
  • Możliwość zastosowania dość potężnych optymalizacji na etapie kompilacji

A oto zalety tłumaczonych języków:

  • Łatwiejszy do wdrożenia (pisanie dobrych kompilatorów jest bardzo trudne !!)
  • Nie ma potrzeby uruchamiania etapu kompilacji: można wykonać kod bezpośrednio „w locie”
  • Może być wygodniejszy dla języków dynamicznych

Zauważ, że nowoczesne techniki, takie jak kompilacja kodu bajtowego, dodają pewnej dodatkowej złożoności - w tym przypadku kompilator jest ukierunkowany na „maszynę wirtualną”, która nie jest taka sama jak sprzęt. Te instrukcje maszyny wirtualnej można następnie ponownie skompilować na późniejszym etapie, aby uzyskać kod macierzysty (np. Tak jak robi to kompilator Java JVM JIT).


1
Nie wszystkie skompilowane języki wymagają powolnego etapu kompilacji. Poważne implementacje Common Lisp są kompilatorami i często nie przeszkadzają interpretatorowi, wolą po prostu kompilować naprawdę szybko w locie. Z drugiej strony Java wymaga kroku kompilacji i zwykle jest widoczna.
David Thornley,

2
@Kareem: kompilator JIT robi tylko 1) i 2) tylko raz - potem jest to kod natywny do końca. Tłumacz musi wykonać zarówno 1), jak i 2) za każdym razem, gdy wywoływany jest kod (który może być wiele, wiele razy ...). Z czasem kompilator JIT wygrywa o długi margines.
mikera

3
Tak, kod bajtowy jest tłumaczony na kod maszynowy w pewnym momencie podczas całego wykonywania programu (w przeciwieństwie do wykonywania przed programem, jak ma to miejsce w przypadku tradycyjnego kompilatora). Ale dany fragment kodu może zostać wykonany ponad 10 milionów razy podczas całego wykonywania programu. (Prawdopodobnie) kompiluje się tylko raz z kodu bajtowego na kod maszynowy. W związku z tym narzut JIT jest niewielki i można go zignorować w przypadku długo działających programów. Po zakończeniu pracy kompilatora JIT efektywnie uruchomisz czysty kod maszynowy.
mikera

2
To właściwie fałszywa dychotomia. Nie ma nic wspólnego z językiem, który zmusza go do skompilowania naszej interpretacji. To nic innego jak szeroko rozpowszechnione nieporozumienie. Wiele języków ma zarówno implementacje, jak i wszystkie języki.
mmachenry

2
@mmachenry to nie jest fałszywa dychotomia. „język programowania” obejmuje zarówno projekt, jak i wdrożenie. Podczas gdy w sensie teoretycznym daną definicję języka można zarówno skompilować, jak i zinterpretować, w praktyce w świecie rzeczywistym istnieją znaczne różnice we wdrażaniu. Nikt jeszcze nie wyjaśnił, jak na przykład skutecznie kompilować niektóre konstrukcje językowe - jest to otwarty problem badawczy.
mikera

99

Sam język nie jest ani kompilowany, ani interpretowany, a jedynie jego konkretna implementacja. Java jest doskonałym przykładem. Istnieje platforma oparta na kodzie bajtowym (JVM), natywny kompilator (gcj) i interpeter dla nadzbioru Java (bsh). Czym jest teraz Java? Kompilowany w bajtkodzie, kompilowany w natywny czy interpretowany?

Inne języki, które są kompilowane i interpretowane, to Scala, Haskell lub Ocaml. Każdy z tych języków ma interaktywny interpreter, a także kompilator do kodu bajtowego lub natywnego kodu maszynowego.

Tak więc ogólne dzielenie języków na „skompilowane” i „zinterpretowane” nie ma większego sensu.


3
Zgadzam się. Albo powiedzmy: istnieją natywne kompilatory (tworzące kod maszynowy dla procesora do zjedzenia) i nie tak natywne-kompilatory (tworzą tokenizowane rzeczy, tj. Kod pośredni, które niektóre kompilatory just-in-time kompilują wcześniej do kodu maszynowego ( lub podczas) środowiska wykonawczego RAZ) i istnieją „prawdziwe” niekompilatory, które nigdy nie produkują kodu maszynowego i nigdy nie pozwalają procesorowi na uruchomienie kodu. Ci ostatni są tłumaczami ustnymi. Obecnie natywne kompilatory, które bezpośrednio wytwarzają kod maszynowy (CPU) w czasie kompilacji stają się coraz rzadsze. Delphi / Codegear jest jednym z najlepszych, którzy przeżyli.
TheBlastOne,

57

Zacznij myśleć w kategoriach: wybuchu z przeszłości

Dawno, dawno temu żył w krainie tłumaczy komputerowych i kompilatorów. Rozgorzały wszelkiego rodzaju zamieszania nad zaletami jednego nad drugim. Ogólna opinia w tym czasie była następująca:

  • Tłumacz: szybki do opracowania (edycja i uruchomienie). Powolne do wykonania, ponieważ każda instrukcja musiała być interpretowana w kodzie maszynowym za każdym razem, gdy była wykonywana (pomyśl o tym, co to znaczy dla pętli wykonywanej tysiące razy).
  • Kompilator: Powolny rozwój (edycja, kompilacja, łączenie i uruchamianie. Kroki kompilacji / łączenia mogą zająć dużo czasu). Szybki do wykonania. Cały program był już w natywnym kodzie maszynowym.

Między interpretowanym programem a programem kompilowanym istniała różnica w wydajności w czasie wykonywania o jeden lub dwa rzędy wielkości. Inne punkty odróżniające, na przykład zmienność kodu w czasie wykonywania, również były interesujące, ale główne rozróżnienie dotyczyło problemów z wydajnością w czasie wykonywania.

Dzisiaj krajobraz ewoluował do tego stopnia, że ​​skompilowane / interpretowane rozróżnienie jest praktycznie nieistotne. Wiele skompilowanych języków wymaga usług w czasie wykonywania, które nie są całkowicie oparte na kodzie maszynowym. Ponadto większość interpretowanych języków jest „kompilowana” w kod bajtowy przed wykonaniem. Interpretatory kodu bajtowego mogą być bardzo wydajne i rywalizować z niektórymi kodami generowanymi przez kompilator z punktu widzenia szybkości wykonywania.

Klasyczna różnica polega na tym, że kompilatory generują natywny kod maszynowy, tłumacze odczytują kod źródłowy i generują kod maszynowy w locie za pomocą jakiegoś systemu wykonawczego. Obecnie pozostało bardzo mało klasycznych interpreterów - prawie wszystkie z nich kompilują się w kod bajtowy (lub inny stan częściowo skompilowany), który następnie działa na wirtualnej „maszynie”.


1
Fajnie - świetne podsumowanie w ostatnim akapicie - dzięki!
ckib16

26

Ekstremalne i proste przypadki:

  • Kompilator wygeneruje binarny plik wykonywalny w natywnym formacie wykonywalnym komputera docelowego. Ten plik binarny zawiera wszystkie wymagane zasoby z wyjątkiem bibliotek systemowych; jest gotowy do działania bez dalszego przygotowania i przetwarzania i działa jak błyskawica, ponieważ kod jest rodzimym kodem dla procesora na maszynie docelowej.

  • Interpreter wyświetli użytkownikowi monit w pętli, w którym może wprowadzić instrukcje lub kod, a po naciśnięciu RUNlub równorzędnym interpreter zbada, zeskanuje, przeanalizuje i wykona interpretacyjnie każdą linię, dopóki program nie osiągnie punktu zatrzymania lub błędu . Ponieważ każda linia jest traktowana osobno, a tłumacz nie „uczy się” niczego po tym, jak ją wcześniej widział, wysiłek konwersji języka czytelnego dla człowieka na instrukcje maszynowe jest podejmowany za każdym razem dla każdej linii, więc jest wolny. Z drugiej strony, użytkownik może kontrolować i w inny sposób wchodzić w interakcje ze swoim programem na różne sposoby: zmieniając zmienne, zmieniając kod, uruchamiając tryb śledzenia lub debugowania ... cokolwiek.

Po ich usunięciu pozwól mi wyjaśnić, że życie nie jest już takie proste. Na przykład,

  • Wielu tłumaczy wstępnie skompiluje otrzymany kod, więc krok tłumaczenia nie musi być powtarzany wielokrotnie.
  • Niektóre kompilatory kompilują się nie według instrukcji maszyny specyficznych dla procesora, ale do kodu bajtowego, rodzaju sztucznego kodu maszynowego dla fikcyjnej maszyny. To sprawia, że ​​skompilowany program jest nieco bardziej przenośny, ale wymaga interpretera kodu bajtowego w każdym systemie docelowym.
  • Interpretatory kodu bajtowego (tutaj patrzę na Javę) ostatnio mają tendencję do ponownej kompilacji kodu bajtowego, który otrzymują dla CPU sekcji docelowej tuż przed wykonaniem (zwanej JIT). Aby zaoszczędzić czas, często dzieje się tak tylko w przypadku często uruchamianego kodu (hotspotów).
  • Niektóre systemy, które wyglądają i działają jak tłumacze (na przykład Clojure), kompilują natychmiast otrzymany kod, ale umożliwiają interaktywny dostęp do środowiska programu. Jest to w zasadzie wygoda tłumaczy z prędkością kompilacji binarnej.
  • Niektóre kompilatory tak naprawdę nie kompilują, po prostu wstępnie przetwarzają i kompresują kod. Jakiś czas temu usłyszałem, jak działa Perl. Czasami więc kompilator wykonuje tylko trochę pracy, a większość z nich jest nadal interpretacją.

Ostatecznie w dzisiejszych czasach tłumaczenie ustne i kompilacja jest kompromisem, a czas spędzony (raz) na kompilacji jest często nagradzany lepszą wydajnością środowiska wykonawczego, ale środowisko interpretacyjne daje więcej możliwości interakcji. Kompilowanie a tłumaczenie ustne polega głównie na tym, jak praca nad „zrozumieniem” programu jest podzielona na różne procesy, a linia jest dziś nieco rozmazana, ponieważ języki i produkty starają się oferować to, co najlepsze z obu światów.


23

Od http://www.quora.com/What-is-the-difference-between-compiled-and-interpreted-programming-languages

Nie ma różnicy, ponieważ „skompilowany język programowania” i „interpretowany język programowania” nie są znaczącymi pojęciami. Każdy język programowania, a naprawdę mam na myśli każdy, może być interpretowany lub kompilowany. Zatem interpretacja i kompilacja są technikami implementacyjnymi, a nie atrybutami języków.

Tłumaczenie ustne to technika, w której inny program, tłumacz, wykonuje operacje w imieniu interpretowanego programu w celu jego uruchomienia. Jeśli potrafisz sobie wyobrazić czytanie programu i robienie tego, co mówi krok po kroku, powiedz na skrawku papieru, to właśnie robi tłumacz. Częstym powodem interpretacji programu jest to, że tłumacze są stosunkowo łatwi do napisania. Innym powodem jest to, że interpreter może monitorować, co program robi w trakcie działania, aby egzekwować zasady, powiedzmy, dotyczące bezpieczeństwa.

Kompilacja to technika, w której program napisany w jednym języku („język źródłowy”) jest tłumaczony na program w innym języku („język obiektowy”), co, mam nadzieję, oznacza to samo, co program oryginalny. Podczas tłumaczenia kompilator często próbuje również przekształcić program w taki sposób, aby przyspieszyć działanie programu obiektowego (bez zmiany jego znaczenia!). Częstym powodem kompilacji programu jest to, że istnieje dobry sposób na szybkie uruchamianie programów w języku obiektowym bez konieczności interpretowania języka źródłowego.

Być może zgadłeś na podstawie powyższych definicji, że te dwie techniki implementacji nie wykluczają się wzajemnie, a nawet mogą się uzupełniać. Tradycyjnie językiem obiektowym kompilatora był kod maszynowy lub coś podobnego, co odnosi się do dowolnej liczby języków programowania rozumianych przez poszczególne procesory komputerowe. Kod maszynowy działałby wtedy „na metalu” (choć można by zobaczyć, jeśli przyjrzeć się wystarczająco uważnie, że „metal” działa podobnie jak tłumacz). Dziś jednak bardzo często używa się kompilatora do generowania kodu obiektowego, który ma być interpretowany - na przykład tak działa Java (a czasem nadal działa). Istnieją kompilatory, które tłumaczą inne języki na JavaScript, który jest następnie często uruchamiany w przeglądarce internetowej, która może interpretować JavaScript, lub skompiluj to maszynę wirtualną lub kod macierzysty. Posiadamy również interpretatory kodu maszynowego, których można użyć do emulacji jednego rodzaju sprzętu na innym. Lub można użyć kompilatora do wygenerowania kodu obiektowego, który jest następnie kodem źródłowym innego kompilatora, który może nawet skompilować kod w pamięci w samą porę, aby go uruchomić, co z kolei. . . Masz pomysł. Istnieje wiele sposobów łączenia tych pojęć.


Czy możesz naprawić to zdanie: „Istnieją kompilatory, które tłumaczą inne języki na JavaScript, który jest następnie często uruchamiany w przeglądarce internetowej, która może interpretować JavaScript lub skompilować go na maszynie wirtualnej lub natywnym kodzie”.
Koray Tugay

Przybiłam to. Innym częstym błędem jest przypisywanie użyteczności języka istniejącym interfejsom API.
Little Endian

10

Największą przewagą interpretowanego kodu źródłowego nad skompilowanym kodem źródłowym jest PRZENOŚNOŚĆ .

Jeśli Twój kod źródłowy jest skompilowany, musisz skompilować inny plik wykonywalny dla każdego typu procesora i / lub platformy, na której chcesz uruchomić program (np. Jeden dla Windows x86, jeden dla Windows x64, jeden dla Linux x64 i tak dalej na). Ponadto, o ile Twój kod nie jest w pełni zgodny ze standardami i nie korzysta z funkcji / bibliotek specyficznych dla platformy, będziesz musiał napisać i utrzymywać wiele baz kodu!

Jeśli Twój kod źródłowy zostanie zinterpretowany, musisz go napisać tylko raz i może on zostać zinterpretowany i wykonany przez odpowiedniego tłumacza na dowolnej platformie! Jest przenośny ! Należy pamiętać, że sam interpreter jest program wykonywalny, który jest napisany i skompilowany dla konkretnej platformy.

Zaletą skompilowanego kodu jest to, że ukrywa on kod źródłowy przed użytkownikiem końcowym (który może być własnością intelektualną ), ponieważ zamiast wdrożyć oryginalny kod źródłowy czytelny dla człowieka, wdrażasz niejasny binarny plik wykonywalny.


1
na tych warunkach java nie może być uważana za „język kompilowany”, ale jego faza kompilacji daje zalety kompilacji (sprawdzanie typu, wczesne wykrywanie błędów itp.) i tworzy kod bajtowy, który można uruchomić w każdym systemie operacyjnym z Javą zapewniona maszyna wirtualna.
Rogelio Triviño

7

Kompilator i tłumacz wykonują to samo zadanie: tłumaczą język programowania na inny język pgoramming, zwykle bliższy sprzętowi, często bezpośrednio wykonywalny kod maszynowy.

Tradycyjnie „skompilowane” oznacza, że ​​to tłumaczenie odbywa się za jednym razem, jest wykonywane przez programistę, a wynikowy plik wykonywalny jest dystrybuowany do użytkowników. Czysty przykład: C ++. Kompilacja zwykle trwa dość długo i próbuje wykonać wiele kosztownej optymalizacji, aby wynikowy plik wykonywalny działał szybciej. Użytkownicy końcowi nie mają narzędzi i wiedzy do samodzielnego kompilowania rzeczy, a plik wykonywalny często musi działać na różnych urządzeniach, więc nie można przeprowadzić wielu optymalizacji specyficznych dla sprzętu. Podczas opracowywania osobny etap kompilacji oznacza dłuższy cykl sprzężenia zwrotnego.

Tradycyjnie „interpretowany” oznacza, że ​​tłumaczenie odbywa się „w locie”, gdy użytkownik chce uruchomić program. Czysty przykład: waniliowy PHP. Naiwny interpreter musi analizować i tłumaczyć każdy fragment kodu za każdym razem, gdy jest uruchamiany, co czyni go bardzo wolnym. Nie można wykonywać skomplikowanych, kosztownych optymalizacji, ponieważ zajęłyby one więcej czasu niż czas zaoszczędzony na wykonaniu. Ale może w pełni wykorzystać możliwości sprzętu, na którym działa. Brak oddzielnego kroku kompilacji skraca czas sprzężenia zwrotnego podczas programowania.

Ale w dzisiejszych czasach „kompilacja vs. interpretacja” nie jest kwestią czarno-białą, między nimi są cienie. Naiwni, prości tłumacze wymarli. Wiele języków korzysta z dwuetapowego procesu, w którym kod wysokiego poziomu jest tłumaczony na niezależny od platformy kod bajtowy (który jest znacznie szybszy do interpretacji). Następnie masz „kompilatory just in time”, które kompilują kod maksymalnie raz na uruchomienie programu, czasami buforują wyniki, a nawet inteligentnie decydują się na interpretację kodu, który jest uruchamiany rzadko, i wykonują potężne optymalizacje dla kodu, który często działa. Podczas programowania debuggery mogą przełączać kod w działającym programie, nawet w przypadku tradycyjnie skompilowanych języków.


1
Jednak model kompilacji C ++ jest dziedziczony z C i został zaprojektowany bez uwzględnienia funkcji takich jak szablony. Ta niezręczność przyczynia się do długiego czasu kompilacji C ++ znacznie bardziej niż jakikolwiek inny czynnik - i czyni go słabym przykładem.

4

Po pierwsze, wyjaśnienie, że Java nie jest w pełni skompilowana statycznie i połączona w sposób C ++. Jest on kompilowany do kodu bajtowego, który jest następnie interpretowany przez JVM. JVM może iść na kompilację „just in time” do natywnego języka maszynowego, ale nie musi tego robić.

Co więcej: myślę, że interaktywność jest główną praktyczną różnicą. Ponieważ wszystko jest interpretowane, możesz pobrać mały fragment kodu, przeanalizować go i uruchomić w stosunku do bieżącego stanu środowiska. Tak więc, jeśli już wykonałeś kod inicjujący zmienną, miałbyś dostęp do tej zmiennej itp. Naprawdę nadaje się do takich rzeczy jak styl funkcjonalny.

Jednak interpretacja kosztuje dużo, zwłaszcza gdy masz duży system z wieloma referencjami i kontekstem. Z definicji jest to marnotrawstwo, ponieważ identyczny kod może wymagać dwukrotnej interpretacji i optymalizacji (chociaż większość środowisk wykonawczych ma w tym celu pewne buforowanie i optymalizację). Mimo to płacisz za środowisko wykonawcze i często potrzebujesz środowiska wykonawczego. Mniej prawdopodobne jest również, że zobaczysz złożone optymalizacje międzyproceduralne, ponieważ obecnie ich wydajność nie jest wystarczająco interaktywna.

Dlatego w przypadku dużych systemów, które nie ulegną znacznym zmianom, a dla niektórych języków bardziej sensowne jest prekompilowanie i prelinkowanie wszystkiego, wykonaj wszystkie optymalizacje, które możesz zrobić. Kończy się to bardzo oszczędnym środowiskiem uruchomieniowym, które jest już zoptymalizowane dla docelowej maszyny.

Jeśli chodzi o generowanie plików wykonywalnych, ma to niewiele wspólnego z IMHO. Często można utworzyć plik wykonywalny z kompilowanego języka. Ale możesz również utworzyć plik wykonywalny z języka interpretowanego, z wyjątkiem tego, że interpreter i środowisko wykonawcze są już spakowane w wymaganym i ukryte przed tobą. Oznacza to, że generalnie nadal ponosisz koszty środowiska wykonawczego (chociaż jestem pewien, że w przypadku niektórych języków istnieją sposoby na przetłumaczenie wszystkiego na plik wykonywalny drzewa).

Nie zgadzam się, że wszystkie języki można uczynić interaktywnymi. Niektóre języki, takie jak C, są tak powiązane z maszyną i całą strukturą linków, że nie jestem pewien, czy możesz stworzyć sensowną, w pełni funkcjonalną wersję interaktywną


C nie jest tak naprawdę związany z „maszyną”. Składnia i semantyka języka C są raczej proste. Implementacja interpretera języka C nie powinna być szczególnie trudna, tylko bardzo czasochłonna (ponieważ należy również zaimplementować bibliotekę standardową). Poza tym Java może zostać skompilowana do natywnego kodu maszynowego (przy użyciu gcj).
lunaryorn

@lunaryorn: Nie zgadzam się na temat GCJ. GCJ zapewnia jedynie środowisko oparte na plikach wykonywalnych. „Skompilowane aplikacje są połączone z środowiskiem wykonawczym GCJ, libgcj, który zapewnia biblioteki klas podstawowych, moduł wyrzucania elementów bezużytecznych i interpreter kodu bajtowego”
Uri

2
GCJ nie tworzyć natywne kodu maszynowego, a nie tylko środowisko wykonywalny z wbudowanym tłumaczem i kodu bajtowego. libgcj udostępnia interpreter kodu bajtowego do obsługi wywołań kodu natywnego do kodu bajtowego Java, a nie do interpretacji skompilowanego programu. Jeśli libgcj nie dostarczy interpretera kodu bajtowego, GCJ nie będzie zgodny ze specyfikacją Java.
lunaryorn

@lunaryorn: Ah. Ok, doceniam wyjaśnienie i poprawiam stanowisko. Używamy głównie Java w środowisku Windows, więc od lat nie próbowałem gcj.
Uri


2

Trudno jest udzielić praktycznej odpowiedzi, ponieważ różnica dotyczy samej definicji języka. Możliwe jest zbudowanie interpretera dla każdego skompilowanego języka, ale nie jest możliwe zbudowanie kompilatora dla każdego przetłumaczonego języka. Chodzi przede wszystkim o formalną definicję języka. Tak, że teoretyczne rzeczy, które noboby lubi na uniwersytecie.


1
Z pewnością możesz zbudować kompilator dla języka interpretowanego, ale sam skompilowany kod maszynowy jest zwierciadłem środowiska wykonawczego.
Aiden Bell

2

Książka Python © 2015 Imagine Publishing Ltd, po prostu rozróżnia różnicę, podając następującą wskazówkę wymienioną na stronie 10 jako:

Językiem interpretowanym, takim jak Python, jest język, w którym kod źródłowy jest konwertowany na kod maszynowy, a następnie uruchamiany przy każdym uruchomieniu programu. Różni się to od skompilowanego języka, takiego jak C, w którym kod źródłowy jest konwertowany na kod maszynowy tylko raz - wynikowy kod maszynowy jest następnie wykonywany przy każdym uruchomieniu programu.


1

Kompilacja to proces tworzenia programu wykonywalnego z kodu napisanego w skompilowanym języku programowania. Kompilacja pozwala komputerowi na uruchomienie i zrozumienie programu bez konieczności używania oprogramowania do jego tworzenia. Podczas kompilacji program jest często kompilowany dla konkretnej platformy (np. Platformy IBM), która działa z komputerami kompatybilnymi z IBM, ale nie z innymi platformami (np. Platformą Apple). Pierwszy kompilator został opracowany przez Grace Hopper podczas pracy na komputerze Harvard Mark I. Obecnie większość języków wysokiego poziomu będzie zawierać własny kompilator lub dostępne zestawy narzędzi, których można użyć do kompilacji programu. Dobrym przykładem kompilatora używanego z Javą jest Eclipse, a przykładem kompilatora używanego z C i C ++ jest komenda gcc.


0

Krótka (nieprecyzyjna) definicja:

Skompilowany język: Cały program jest natychmiast tłumaczony na kod maszynowy, następnie kod maszynowy jest uruchamiany przez CPU.

Tłumaczony język: Program jest odczytywany wiersz po wierszu i natychmiast po odczytaniu wiersza instrukcje maszyny dla tego wiersza są wykonywane przez CPU.

Ale tak naprawdę niewiele języków jest obecnie skompilowanych lub interpretowanych, często jest to mieszanka. Aby uzyskać bardziej szczegółowy opis ze zdjęciami, zobacz ten wątek:

Jaka jest różnica między kompilacją a interpretacją?

Lub mój późniejszy post na blogu:

https://orangejuiceliberationfront.com/the-difference-between-compiler-and-interpreter/

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.