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?
java
python
compiler-construction
programming-languages
interpreter
chimerakoder
źródło
źródło
Odpowiedzi:
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:
A oto zalety tłumaczonych języków:
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).
źródło
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.
źródło
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:
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”.
źródło
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
RUN
lub 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,
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.
źródło
Od http://www.quora.com/What-is-the-difference-between-compiled-and-interpreted-programming-languages
źródło
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.
źródło
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.
źródło
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ą
źródło
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.
źródło
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:
źródło
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.
źródło
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/
źródło