Według mojej wiedzy nie ma czegoś takiego jak interpretowany „język” lub skompilowany „język”.
Języki określają składnię i znaczenie słów kluczowych kodu, konstrukcji przepływu i różnych innych rzeczy, ale nie znam żadnego języka, który określa, czy należy go skompilować lub interpretować w specyfikacji języka.
Teraz, gdy masz pytanie, kiedy używasz kompilatora językowego kontra tłumacza językowego, tak naprawdę sprowadza się to do zalet / wad kompilatora vs. tłumacza i celu projektu.
Na przykład możesz użyć kompilatora JRuby dla łatwiejszej integracji z bibliotekami Java zamiast interpretera ruby MRI. Prawdopodobnie istnieją również powody, aby używać interpretera ruby MRI w JRuby, chociaż nie znam tego języka i nie mogę z tym rozmawiać.
Reklamowane zalety tłumaczy:
- Brak kompilacji oznacza, że czas od edycji kodu do przetestowania aplikacji może zostać skrócony
- Nie ma potrzeby generowania plików binarnych dla wielu architektur, ponieważ interpreter będzie zarządzał abstrakcją architektury (chociaż może być konieczne martwienie się o to, że skrypty poprawnie obsługują rozmiary całkowite, a nie dystrybucję binarną)
Proponowane zalety kompilatorów:
- Skompilowany kod natywny nie ma narzutu interpretera i dlatego zwykle jest bardziej wydajny pod względem czasu i przestrzeni
- Interoperacyjność jest zwykle lepsza, jedynym sposobem na współpracę in-proc ze skryptami jest interpreter, a nie standardowa FFI
- Możliwość obsługi architektur, dla których interpreter nie został skompilowany (takich jak systemy osadzone)
Założę się jednak, że w 90% przypadków będzie to wyglądać mniej więcej tak: chcę napisać to oprogramowanie w blubie, ponieważ dobrze go znam i powinno być dobre. Użyję interpretera (lub kompilatora) blub, ponieważ jest to ogólnie przyjęta kanoniczna metoda pisania oprogramowania w blubie.
Tak więc TL; DR jest po prostu, porównanie poszczególnych interpretatorów z kompilatorami dla konkretnego przypadku użycia.
Ponadto FFI: Interfejs funkcji zagranicznych, innymi słowy interfejs do współpracy z innymi językami. Więcej lektur na wikipedii
Ważną kwestią jest to, że wiele implementacji językowych faktycznie łączy w sobie jakąś hybrydę. Wiele powszechnie używanych języków działa dzisiaj, kompilując program do formatu pośredniego, takiego jak kod bajtowy, a następnie uruchamiając go w tłumaczu. W ten sposób zazwyczaj implementowane są Java, C #, Python, Ruby i Lua. W rzeczywistości jest to zapewne sposób, w jaki większość obecnie używanych języków jest wdrażana. Faktem jest, że dzisiejszy język interpretuje i kompiluje kod. Niektóre z tych języków mają dodatkowy kompilator JIT do konwersji kodu bajtowego na kod macierzysty w celu wykonania.
Moim zdaniem powinniśmy przestać mówić o językach interpretowanych i kompilowanych, ponieważ nie są one już kategoriami użytecznymi do rozróżniania złożoności dzisiejszych implementacji językowych.
Kiedy pytasz o zalety tłumaczonych i skompilowanych języków, prawdopodobnie masz na myśli coś innego. Być może pytasz o zalety pisania statycznego / dynamicznego, zalety dystrybucji natywnych plików wykonywalnych, względne zalety kompilacji JIT i AOT. Są to wszystkie problemy, które łączą się z interpretacją / kompilacją, ale są różnymi zagadnieniami.
źródło
Przede wszystkim język programowania można interpretować i kompilować. Interpretacja i kompilacja to tylko metody generowania kodu wykonywalnego z kodu źródłowego. W przypadku interpretera kod źródłowy jest odczytywany i interpretowany przez interpretera, który następnie wykonuje kod podczas jego interpretacji. Z drugiej strony kompilator odczytuje kod źródłowy i generuje wykonywalny plik binarny z kodu źródłowego - dzięki czemu program może być uruchamiany jako osobny proces niezależnie.
Teraz, zanim ktokolwiek się zastanowi ... Tak, C / C ++ / C # / Java można interpretować i tak, można skompilować skrypty JavaScript i Bash. To, czy istnieją działający tłumacze ustni lub kompilatory dla tych języków, to kolejne pytanie.
Teraz, aby odpowiedzieć na pytanie, kiedy użyjemy „języka interpretowanego” zamiast „języka skompilowanego”. Samo pytanie jest nieco mylące, ale zakładam, że oznacza to, kiedy wolę interpretację niż kompilację. Jedną z wad kompilacji jest to, że generuje pewne obciążenie z powodu procesu kompilacji - kod źródłowy musi zostać skompilowany do wykonywalnego kodu maszynowego, więc nie nadaje się do zadań wymagających minimalnego opóźnienia podczas wywoływania kodu źródłowego w celu wykonania programu. Z drugiej strony skompilowany kod źródłowy jest prawie zawsze szybszy niż równoważny zinterpretowany kod źródłowy z powodu narzutu spowodowanego interpretacją kodu. Z drugiej strony tłumacze mogą wywoływać i uruchamiać kod źródłowy z bardzo małym narzutem wywołania, ale kosztem wydajności w czasie wykonywania.
W końcu prawie niemożliwe jest podanie jakichkolwiek konkretnych przypadków użycia, kiedy wolą jeden po drugim, ale na przykład jeden (do mojego podkreślającego, bardzo nierealistycznego) przypadek byłby, gdy kod źródłowy programu zmienia się dynamicznie między wywołaniami programu, a narzut kompilacji jest zbyt duży wysoki, aby był to realny wybór. W takim przypadku prawdopodobnie pożądana byłaby interpretacja kodu źródłowego zamiast kompilacji.
Istnieje jednak coś, co można uznać za przykład z prawdziwego świata: ukrywanie kodu źródłowego po wdrożeniu. Z natywnieskompilowany kod programista wdraża wykonywalny kod macine programu i danych. W przypadku interpretowanego kodu należy wdrożyć sam kod źródłowy, który można następnie sprawdzić i poddać inżynierii wstecznej przy znacznie mniejszym nakładzie pracy niż w przypadku natywnego kodu maszynowego. Jedynym wyjątkiem są języki takie jak C # i Java, które kompilują się do bezpośredniego języka / kodu bajtowego (MSIL dla C # i kodu bajtowego Java dla Java), które następnie są wdrażane i kompilowane „na czas” w czasie wykonywania, podobnie jak robi to interpreter. Istnieją jednak tak zwane dekompilatory dla MSIL i Java Bytecode, które mogą rekonstruować oryginalny kod źródłowy ze względnie dobrą dokładnością i jako takie, inżynieria wsteczna takich produktów jest znacznie bardziej trywialna niż produkty inżynierii wstecznej, które są wdrażane w natywnym kodzie maszynowym.
źródło
Mogę wymyślić następujące scenariusze, gdy używasz tłumaczonego języka:
Mogę wymyślić następujące scenariusze, gdy chcesz skompilować kod:
źródło
Ostatecznie duży kompromis polega na produktywności (ile linii kodu musisz napisać) i wydajności (jak szybko twój program wykona).
Ponieważ języki interpretowane po przekształceniu w informacje o procesorze zawierają więcej informacji, mogą polegać na refleksji i dynamicznym pisaniu, co znacznie zwiększa wydajność . Kolejną zaletą języków interpretowanych jest to, że są one niezależne od platformy, o ile istnieje platforma dla tłumacza.
Ponieważ procesor nie może przekształcać kodu języka w kod maszynowy i uruchamiać go w tym samym czasie, jak w interpretowanym przypadku, języki kompilowane dają szybsze programy. Ponadto system wbudowany w język kompilowany jest bezpieczniejszy, ponieważ może wykrywać problemy w czasie kompilacji, co w zasadzie oznacza, że widzisz błąd podczas pisania (z nowoczesnymi IDE) zamiast go widzieć tylko wtedy, gdy faktycznie uruchomisz program (oczywiście , to nie naprawia błędów logicznych).
Znając to, tłumaczone języki są odpowiednie dla:
Języki skompilowane są odpowiednie, gdy:
źródło
Oprócz powodów, o których wspominali inni, istnieje jeden szczególnie ważny przypadek użycia przy wyborze interpretacji ad hoc zamiast dowolnej formy kompilacji lub dowolnego podejścia hybrydowego.
W przypadku, gdy język programowania jest używany jako protokół komunikacyjny i gdy ważne jest opóźnienie odpowiedzi, bardziej sensowne jest unikanie marnowania czasu na kompilację i ewentualne przetwarzanie wstępne.
Dotyczy to na przykład języków agentów lub sposobu, w jaki, powiedzmy, Tcl / Tk jest zwykle używany.
Innym możliwym powodem trzymania się interpretacji jest użycie interpretera języka do samego ładowania lub bardziej rozbudowanego języka wyższego poziomu, a jego prostota jest ważniejsza niż wydajność procesu ładowania.
Dla prawie każdego innego możliwego przypadku użycia kompilacja (lub podejście hybrydowe) jest lepszym rozwiązaniem.
źródło