Skompilowane a interpretowane języki

Staram się lepiej zrozumieć różnicę. Znalazłem wiele wyjaśnień w Internecie, ale mają tendencję do abstrakcyjnych różnic, a nie praktycznych implikacji.

Większość moich doświadczeń programistycznych dotyczyła CPython (dynamiczna, interpretowana) i Java (statyczna, skompilowana). Rozumiem jednak, że istnieją inne rodzaje języków interpretowanych i kompilowanych. Pomijając fakt, że pliki wykonywalne mogą być dystrybuowane z programów napisanych w skompilowane języki, czy są jakieś zalety/wady każdego typu? Często słyszę, jak ludzie argumentują, że języki interpretowane mogą być używane interaktywnie, ale wierzę, że języki skompilowane mogą mieć również interaktywne implementacje, prawda?

Author: starblue, 2010-07-16

11 answers

Skompilowany język to taki, w którym program, raz skompilowany, jest wyrażany w instrukcjach maszyny docelowej. Na przykład dodatkowa operacja " + "w kodzie źródłowym może być przetłumaczona bezpośrednio na instrukcję "Dodaj" w kodzie maszynowym.

Język interpretowany to taki, w którym instrukcje nie są wykonywane bezpośrednio przez maszynę docelową, ale zamiast tego są odczytywane i wykonywane przez inny program (który normalnie jest napisany w języku rodzimej maszyny). Na przykład, ta sama operacja "+" byłaby rozpoznawana przez interpreter w czasie wykonywania, który następnie wywołałby własną funkcję" add (a,b)" z odpowiednimi argumentami, który następnie wykonałby instrukcję "ADD" kodu maszynowego.

Możesz zrobić wszystko, co możesz zrobić w języku interpretowanym w języku skompilowanym i odwrotnie - oba są pełne Turinga. Oba mają jednak zalety i wady w zakresie wdrażania i użytkowania.

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

  • szybsza wydajność poprzez bezpośrednie użycie kodu natywnego docelowej maszyny
  • możliwość zastosowania dość potężnych optymalizacji na etapie kompilacji

A oto zalety języków interpretowanych:

  • łatwiejsze do zaimplementowania (pisanie dobrych kompilatorów jest bardzo trudne!!)
  • nie ma potrzeby uruchamiania etapu kompilacji: można wykonać kod bezpośrednio " na fly "
  • Może być wygodniejszy dla języków dynamicznych

Zauważ, że nowoczesne techniki, takie jak kompilacja kodu bajtowego, dodają dodatkowej złożoności - to, co się tutaj dzieje, to to, że kompilator celuje w "maszynę Wirtualną", która nie jest taka sama jak podstawowy sprzęt. Te instrukcje maszyny wirtualnej mogą być skompilowane ponownie na późniejszym etapie w celu uzyskania kodu natywnego (np. jak to robi kompilator JIT Java JVM).

 399
Author: mikera,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-26 20:48:51

Język sam w sobie nie jest ani kompilowany, ani interpretowany, tylko konkretna implementacja języka jest. Java jest doskonałym przykładem. Istnieje platforma oparta na kodach bajtowych (JVM), natywny kompilator (gcj) i interpeter dla supersetu Javy (bsh). Czym jest teraz Java? Bytecode-skompilowany, natywny-skompilowany czy zinterpretowany?

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

Więc ogólnie kategoryzowanie języków według "skompilowanych" i "zinterpretowanych" nie ma większego sensu.

 88
Author: lunaryorn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-16 14:07:38

Zacznij myśleć w kategoriach: blast from the past

Dawno, dawno temu, żył w Krainie komputerów interpreterów i kompilatorów. Wszelkiego rodzaju zamieszanie związane z zaletami jeden nad drugim. Ogólna opinia w owym czasie była czymś w rodzaju:

  • Interpreter: szybki do opracowania (edycji i uruchomienia). Powolne wykonywanie, ponieważ każda instrukcja musiała być interpretowana na kodu maszynowego przy każdym jego wykonaniu (pomyśl o co to oznaczało dla pętli wykonywanej tysiące razy).
  • kompilator: wolno się rozwija (edytuje, kompiluje, łączy i uruchamia. Kroki kompilacji/linku mogą zająć dużo czasu). Szybko do wykonania. Cały program był już w natywnym kodzie maszynowym.

Jeden lub dwa rzędy wielkości różnicy w czasie trwania wydajność istniała między zinterpretowanym programem a skompilowanym programem. Inne wyróżnienia punkty, np. zmienność kodu w czasie działania, były również przedmiotem zainteresowania ale major rozróżnienie skupiało się wokół kwestii wydajności w czasie pracy.

Dziś krajobraz ewoluował do tego stopnia, że zestawione / zinterpretowane rozróżnienie jest praktycznie nieistotne. Wiele skompilowane języki wymagają usług run-time, które nie są całkowicie oparty na kodzie maszynowym. Ponadto większość języków interpretowanych jest "kompilowanych" do kodu bajtowego przed egzekucją. Interpretery kodu bajtowego mogą być bardzo wydajne i konkurować z generowanymi kompilatorami kod z punktu prędkości wykonania widoku.

Klasyczna różnica polega na tym, że Kompilatory generują natywny kod maszynowy, interpretery odczytują kod źródłowy i generowanie kodu maszynowego w locie za pomocą jakiegoś systemu czasu pracy. Dziś pozostało bardzo niewiele klasycznych tłumaczy-prawie wszyscy skompilować do kodu bajtowego (lub innego częściowo skompilowanego stanu), który następnie uruchamia się na wirtualnej "maszynie".

 46
Author: NealB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-16 14:43:33

Skrajne i proste przypadki:

  • Kompilator stworzy binarny plik wykonywalny w natywnym formacie wykonywalnym maszyny docelowej. 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 natywnym kodem dla procesora na docelowej maszynie.

  • Interpreter wyświetli użytkownikowi monit w pętli, w której może wprowadzić po naciśnięciu RUN lub jej odpowiednika interpreter będzie sprawdzał, skanował, analizował i interpretacyjnie wykonywał każdą linię, dopóki program nie uruchomi się do punktu zatrzymania lub błędu. Ponieważ każda linia jest traktowana samodzielnie, a interpreter nie" uczy się " niczego z oglądania linii wcześniej, wysiłek konwersji języka czytelnego dla człowieka na instrukcje maszynowe jest ponoszony za każdym razem dla każdej linii, więc jest to psie powolne. Z drugiej strony użytkownik może sprawdzić i w przeciwnym razie współdziałaj z jego programem na różne sposoby: zmieniając zmienne, zmieniając kod, uruchamiając w trybie śledzenia lub debugowania... nieważne.

Skoro już ich nie ma, wyjaśnię, że życie nie jest już takie proste. Na przykład,
  • wielu tłumaczy wstępnie skompiluje podany kod, aby krok tłumaczenia nie musiał być powtarzany wielokrotnie.
  • niektóre Kompilatory kompilują się nie do instrukcji maszynowych specyficznych dla procesora, ale do bajtkodu, pewnego rodzaju sztuczny kod maszynowy dla fikcyjnej maszyny. To sprawia, że skompilowany program jest nieco bardziej przenośny, ale wymaga interpretera kodu bajtowego na każdym docelowym systemie.
  • interpretery kodu bajtowego (patrzę tutaj na Javę) mają tendencję do ponownej kompilacji kodu bajtowego, który dostają dla procesora sekcji docelowej tuż przed wykonaniem (zwanego JIT). Aby zaoszczędzić czas, często robi się to tylko dla kodu, który działa często (hotspoty).
  • niektóre systemy, które wyglądają i działają jak Interpretatory (Clojure, dla instancja) skompilować dowolny kod, który otrzymają, natychmiast, ale pozwalają na interaktywny dostęp do środowiska programu. To w zasadzie wygoda interpreterów z szybkością kompilacji binarnej.
  • niektóre Kompilatory tak naprawdę nie kompilują, tylko wstępnie trawią i kompresują kod. Jakiś czas temu słyszałem, że tak działa Perl. Tak więc czasami kompilator wykonuje tylko część pracy, a większość wciąż jest interpretacją.

W końcu, w dzisiejszych czasach, tłumaczenie a kompilowanie jest kompromis, w którym czas spędzony (raz) na kompilacji jest często nagradzany lepszą wydajnością runtime, ale środowiskiem interpretacyjnym dającym więcej możliwości interakcji. Kompilowanie a interpretowanie to głównie kwestia tego, jak praca "rozumienia" programu jest podzielona między różne procesy, a linia jest nieco rozmyta w dzisiejszych czasach, ponieważ Języki i produkty starają się oferować to, co najlepsze z obu światów.

 23
Author: Carl Smotricz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-16 13:52:02

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

Nie ma różnicy, bo "skompilowany język programowania" i "interpretowany język programowania" nie są pojęciami znaczącymi. Dowolne język programowania, a naprawdę mam na myśli każdy, może być interpretowany lub opracowano na podstawie materiału źródłowego. Tak więc interpretacja i Kompilacja są implementacją techniki, a nie atrybuty języków.

Interpretacja jest technika, dzięki której inny program, interpreter, wykonuje operacje w imieniu programu będącego / align = "left" / Jeśli potrafisz sobie wyobrazić czytanie programu i robiąc to, co mówi, krok po kroku, powiedzmy na kawałku drapania papier, tak też robi Tłumacz. Wspólny powód interpretować program jest to, że tłumacze są stosunkowo łatwe do pisz. Innym powodem jest to, że tłumacz może monitorować to, co program próbuje robić to, co działa, aby wymusić Polityka, powiedzmy, dla Ochrona.

Kompilacja to technika polegająca na tym, że program napisany w jednym języku ("język źródłowy") jest tłumaczony na program w innym Język ("object language"), co miejmy nadzieję oznacza to samo jako oryginalny program. Podczas wykonywania tłumaczenia, to jest wspólne dla kompilatora, aby również spróbować przekształcić program w sposób, który będzie spraw, aby program obiektowy był szybszy (bez zmiany jego znaczenia!). A częsty powód kompilacji program jest taki, że jest jakiś dobry sposób na uruchamianie programów w języku obiektowym szybko i bez nakładów interpretacji języka źródłowego po drodze.

Można się domyślić, na podstawie powyższych definicji, że te dwa techniki wdrażania nie wykluczają się wzajemnie, a nawet mogą być komplementarne. Tradycyjnie językiem obiektowym kompilatora był kod maszynowy lub coś podobnego, który odnosi się do dowolnej liczby języki programowania rozumiane przez poszczególnych procesorów komputerowych. Na kod maszynowy będzie wtedy uruchamiany "na metalu "(choć można zobaczyć, jeśli wystarczy przyjrzeć się dokładnie, że "metal" działa jak interpreter). Dziś jednak bardzo często używa się kompilatora do generować kod obiektowy, który ma być interpretowany-na przykład ten tak kiedyś (a czasami nadal) działa Java. Są Kompilatory, które tłumaczą inne języki na JavaScript, który jest wtedy często uruchamiane w przeglądarce internetowej, która może interpretować JavaScript, lub skompiluj go jako maszynę wirtualną lub natywny kod. Mamy również tłumaczy do kodu maszynowego, który może być użyty do emulowania jednego rodzaju sprzętu na kolejny. Lub, można użyć kompilatora do generowania kodu obiektowego, który jest następnie kod źródłowy innego kompilatora, który może nawet skompilować kod w pamięci w sam raz do uruchomienia, co z kolei . . . dostajesz pomysł. Istnieje wiele sposobów łączenia tych pojęć.

 18
Author: Bhavin Shah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-21 13:04:34

Największą zaletą 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 program 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). Co więcej, jeśli twój kod nie jest całkowicie zgodny ze standardami i nie używa żadnych funkcji/bibliotek specyficznych dla platformy, w rzeczywistości będziesz potrzeba pisania i utrzymywania wielu baz kodu!

Jeśli twój kod źródłowy jest interpretowany, musisz go napisać tylko raz i może być interpretowany i wykonywany przez odpowiedni interpreter na dowolnej platformie! To jest Przenośne ! Należy zauważyć, że interpreter sam w sobie jest programem wykonywalnym, który jest napisany i skompilowany dla określonej platformy.

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

 11
Author: Niko Bellic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-25 02:40:19

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

Tradycyjnie, "skompilowany" oznacza, że to tłumaczenie dzieje się za jednym zamachem, jest wykonywane przez dewelopera, a wynikowy plik wykonywalny jest dystrybuowany do użytkowników. Czysty przykład: C++. Kompilacja zwykle trwa dość długo i stara się wykonać wiele kosztownych optmizacji, aby wynikający z niej plik wykonywalny działał szybciej. Użytkownicy końcowi nie mają narzędzi i Wiedzy, aby samodzielnie kompilować rzeczy, a plik wykonywalny często musi działać na różnych urządzeniach, więc nie można wykonać wielu optymalizacji specyficznych dla sprzętu. Podczas tworzenia oddzielny etap kompilacji Oznacza dłuższy cykl sprzężenia zwrotnego.

Tradycyjnie "zinterpretowane" oznacza, że tłumaczenie odbywa się" w locie", gdy użytkownik chce uruchomić program. Czysty przykład: vanilla PHP. Naiwny tłumacz musi analizować i tłumaczyć każdy kawałek kod za każdym razem, gdy działa, co czyni go bardzo wolnym. Nie może wykonywać złożonych, kosztownych optymalizacji, ponieważ zajmował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 etapu kompilacji skraca czas sprzężenia zwrotnego podczas tworzenia.

Ale w dzisiejszych czasach "skompilowany vs. zinterpretowany" nie jest problemem czarno-białym, pomiędzy nimi są odcienie. Naiwne, proste Interpretatory są prawie wymarłe. Wiele języków używa dwuetapowego proces, w którym kod wysokiego poziomu jest tłumaczony na niezależny od platformy bajt (który jest znacznie szybszy do zinterpretowania). Następnie masz Kompilatory "just In time", które kompilują Kod co najwyżej raz na uruchamiany program, czasami wyniki buforowania, a nawet inteligentnie decydują się zinterpretować kod, który jest uruchamiany rzadko, i wykonują potężne optymalizacje dla kodu, który działa dużo. Podczas programowania debuggery są w stanie przełączać kod wewnątrz uruchomionego programu nawet dla tradycyjnie skompilowanych języków.

 6
Author: Michael Borgwardt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-16 14:01:55

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

Bardziej do rzeczy: myślę, że interakcja jest główną praktyczną różnicą. Ponieważ wszystko jest interpretowane, możesz wziąć mały fragment kodu, przeanalizować i uruchomić go zgodnie z aktualnym stanem środowiska. Tak więc, jeśli jeśli już wykonałeś kod, który zainicjował zmienną, będziesz miał dostęp do tej zmiennej, itd. To naprawdę nadaje się do rzeczy takich jak funkcjonalny styl.

Interpretacja kosztuje jednak dużo, zwłaszcza gdy mamy duży system z dużą ilością odniesień i kontekstu. Z definicji jest to marnotrawstwo, ponieważ identyczny kod może być interpretowany i optymalizowany dwukrotnie(chociaż większość środowisk uruchomieniowych ma do tego pewne buforowanie i optymalizacje). Mimo to płacisz koszt wykonania i często potrzebują środowiska uruchomieniowego. Jest również mniej prawdopodobne, aby zobaczyć złożone optymalizacje międzyproceduralne, ponieważ w chwili obecnej ich wydajność nie jest wystarczająco interaktywna.

Dlatego dla dużych systemów, które nie zmienią się zbytnio, i dla niektórych języków, bardziej sensowne jest prekompilowanie i wstępne łączenie wszystkiego, wykonywanie wszystkich optymalizacji, które możesz zrobić. Kończy się to bardzo lean runtime, który jest już zoptymalizowany pod kątem maszyny docelowej.

Co do generowania executbles, to nie ma z tym nic wspólnego, IMHO. Często można utworzyć plik wykonywalny z skompilowanego języka. Ale można również utworzyć plik wykonywalny z języka interpretowanego, z tym wyjątkiem, że interpreter i środowisko uruchomieniowe są już spakowane w pliku wykonywalnym i ukryte przed tobą. Oznacza to, że na ogół nadal płacisz koszty wykonania (chociaż jestem pewien, że dla niektórych języków istnieją sposoby przetłumaczenia wszystkiego na plik wykonywalny drzewa).

Nie zgadzam się, że wszystkie języki mogą być wykonane interaktywne. Niektóre języki, takie jak C, są tak powiązane z maszyną i całą strukturą łącza, że nie jestem pewien, czy można zbudować znaczącą pełnoprawną interaktywną wersję

 4
Author: Uri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-16 13:45:40

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 zinterpretowanego języka. Chodzi w dużej mierze o formalną definicję języka. Więc te teoretyczne rzeczy informatyczne, które nikt nie lubi na Uniwersytecie.

 2
Author: Steven Mohr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-16 13:50:09

The Python Book © 2015 Imagine Publishing Ltd, po prostu rozróżnia następujące wskazówki wymienione na stronie 10 jako:

Język interpretowany, taki jak Python, to taki, w którym kod źródłowy jest konwertowany na kod maszynowy, a następnie wykonywany za każdym razem, gdy program jest uruchamiany. Różni się to od skompilowanego języka, takiego jak C, gdzie kod źródłowy jest konwertowany tylko raz na kod maszynowy – wynikowy kod maszynowy jest wykonywany za każdym razem, gdy program biegnie.

 2
Author: Ahmed Shaban Helwa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-18 13:22:57

Compile to proces tworzenia programu wykonywalnego z kodu napisanego w skompilowanym języku programowania. Kompilowanie umożliwia komputerowi uruchamianie i rozumienie programu bez potrzeby korzystania z oprogramowania programistycznego używanego do jego tworzenia. Gdy program jest kompilowany, jest on często kompilowany dla określonej platformy (np. IBM platform), która współpracuje z komputerami kompatybilnymi z IBM, ale nie z innymi platformami (np. Apple platform). Pierwszy kompilator został opracowany przez Grace Hopper podczas pracy nad Harvard Mark i computer. Obecnie większość języków wysokiego poziomu będzie zawierać własny kompilator lub mieć dostępne zestawy narzędzi, które mogą być użyte do kompilacji programu. Dobrym przykładem kompilatora używanego w Javie jest Eclipse, a przykładem kompilatora używanego w C i C++ jest polecenie gcc. W zależności od wielkości programu kompilacja powinna zająć kilka sekund lub minut, a jeśli podczas kompilacji nie wystąpią żadne błędy, tworzony jest plik wykonywalny.sprawdź tę informację

 1
Author: salehvm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-17 09:06:10