Beispiele dafür, wann wir interpretierte Sprache gegenüber kompilierter Sprache verwenden?

11

Ich verstehe die Unterschiede zwischen interpretierten und kompilierten Sprachen, aber wenn jemand einige Beispiele für Situationen liefern könnte, in denen man wahrscheinlich interpretierte Sprachen über kompilierte Sprachen verwendet, sowie Situationen, in denen man wahrscheinlich kompilierte Sprachen über interpretierte Sprachen verwendet, würde dies der Fall sein sei wirklich hilfreich.

KL
quelle

Antworten:

11

Es gibt (meines Wissens) keine interpretierte "Sprache" oder kompilierte "Sprache".

Sprachen geben die Syntax und Bedeutung der Schlüsselwörter, Flusskonstrukte und verschiedener anderer Dinge des Codes an, aber mir ist keine Sprache bekannt, die angibt, ob sie in der Sprachspezifikation kompiliert oder interpretiert werden muss oder nicht.

Wenn Sie nun die Frage haben, wann Sie einen Sprachcompiler gegen einen Sprachinterpreter verwenden, kommt es wirklich auf die Vor- und Nachteile des Compilers gegenüber dem Interpreter und den Zweck des Projekts an.

Beispielsweise können Sie den JRuby-Compiler zur einfacheren Integration in Java-Bibliotheken anstelle des MRI-Ruby-Interpreters verwenden. Es gibt wahrscheinlich auch Gründe, den MRT-Ruby-Interpreter über JRuby zu verwenden. Ich bin jedoch mit der Sprache nicht vertraut und kann nicht mit ihr sprechen.

Vorteile von Dolmetschern:

  • Keine Kompilierung bedeutet, dass die Zeit vom Bearbeiten des Codes bis zum Testen der App verkürzt werden kann
  • Es ist nicht erforderlich, Binärdateien für mehrere Architekturen zu generieren, da der Interpreter die Architekturabstraktion verwaltet (obwohl Sie sich möglicherweise immer noch um die Skripte kümmern müssen, die Ganzzahlgrößen korrekt behandeln, nur nicht um die Binärverteilung).

Vorteile von Compilern:

  • Kompilierter nativer Code hat nicht den Overhead eines Interpreters und ist daher in der Regel zeitlich und räumlich effizienter
  • Die Interoperabilität ist normalerweise besser. Die einzige Möglichkeit für die In-Proc-Interoperation mit Skripten besteht in einem Interpreter und nicht in einem Standard-FFI
  • Fähigkeit zur Unterstützung von Architekturen, für die der Interpreter nicht kompiliert wurde (z. B. eingebettete Systeme)

Ich würde jedoch wetten, dass es in 90% der Fälle eher so aussieht : Ich möchte diese Software in blub schreiben, weil ich sie gut kenne und sie einen guten Job machen sollte. Ich werde den Blub-Interpreter (oder Compiler) verwenden, da dies die allgemein akzeptierte kanonische Methode zum Schreiben von Software in Blub ist.

So TL; DR ist im Grunde auf einem von Fall zu Fall Vergleich der Dolmetscher vs den Compiler für Ihren speziellen Anwendungsfall.

Auch FFI: Foreign Function Interface, also Schnittstelle für die Interaktion mit anderen Sprachen. Weitere Informationen finden Sie auf Wikipedia

Jimmy Hoffa
quelle
2
Meines Wissens können einige Skriptsprachen für Betriebssysteme wie ksh für UNIX nicht kompiliert werden.
NoChance
@delnan, mein Punkt ist, dass ich nicht über eine kommerzielle oder freie Software kompilieren kann, von der ich weiß, und nicht, dass sie aus technischen Gründen nicht kompiliert werden kann.
NoChance
3
@EmmadKareem Es gibt kein "kann nicht kompiliert werden". Sie schreiben ein Programm, das ein Programm in der Sprache Li liest und ein äquivalentes Programm in der Sprache La ausgibt. Das ist ein Compiler, ein Compiler. Ich zögere, mich auf das Argument der Vollständigkeit zu berufen, da es in der Praxis ein roter Hering ist, aber jedes Programm wird letztendlich zu einer Folge von Maschinencode-Anweisungen. Wenn alles andere fehlschlägt, rollen Sie die Interpreter-Schleife ab (und vereinfachen Sie den resultierenden Code, um nicht mehr benötigte Teile zu entfernen). Wenn der Interpreter in einer Sprache ohne Interpreter geschrieben ist, wiederholen Sie den Vorgang, bis Sie mit einem Compiler auf etwas stoßen.
1
(Ich habe meinen Kommentar redigiert, um ihn besser auszudrücken, aber anscheinend habe ich zu spät gehandelt.) @EmmadKareem Ja, offensichtlich wurden einige Sprachen nie über einen Compiler implementiert. Aber ich sehe nicht, wie wichtig das ist. Dies ist immer möglich und machbar und kann jederzeit mit etwas Aufwand durchgeführt werden. Dies ist eine Folge des Hauptpunkts, nämlich dass eine Sprache weder inhärent kompiliert noch interpretiert wird und auf beide Arten implementiert werden kann. Und auf unzählige andere Arten (na ja, wohl kleinere Varianten und Remixe) übrigens.
2
@EmmadKareem Wenn Sie möchten, können Sie die ksh-Sprachspezifikation verwenden und einen Compiler schreiben, der sie liest und eine native Binärdatei generiert. Die Sprache, die kompiliert oder interpretiert wird, ist nicht in der Definition einer Sprache enthalten.
Jimmy Hoffa
8

Ein wichtiger Punkt hierbei ist, dass viele Sprachimplementierungen tatsächlich eine Art Hybrid aus beiden ausführen. Viele heute häufig verwendete Sprachen arbeiten, indem sie ein Programm in ein Zwischenformat wie Bytecode kompilieren und dieses dann in einem Interpreter ausführen. So werden normalerweise Java, C #, Python, Ruby und Lua implementiert. In der Tat ist dies wohl die Art und Weise, wie die meisten heute verwendeten Sprachen implementiert werden. Tatsache ist also, dass die heutige Sprache ihren Code sowohl interpretiert als auch kompiliert. Einige dieser Sprachen verfügen über einen zusätzlichen JIT-Compiler, mit dem der Bytecode zur Ausführung in nativen Code konvertiert werden kann.

Meiner Meinung nach sollten wir aufhören, über interpretierte und kompilierte Sprachen zu sprechen, da diese keine nützlichen Kategorien mehr sind, um die Komplexität der heutigen Sprachimplementierungen zu unterscheiden.

Wenn Sie nach den Vorzügen interpretierter und kompilierter Sprachen fragen, meinen Sie wahrscheinlich etwas anderes. Möglicherweise fragen Sie nach den Vorteilen der statischen / dynamischen Typisierung, den Vorteilen der Verteilung nativer ausführbarer Dateien und den relativen Vorteilen der JIT- und AOT-Kompilierung. Dies sind alles Themen, die mit der Interpretation / Zusammenstellung in Konflikt geraten, aber unterschiedliche Themen sind.

Winston Ewert
quelle
2

Zunächst kann eine Programmiersprache sowohl interpretiert als auch kompiliert werden. Interpretation und Kompilierung sind nur Methoden zum Generieren von ausführbarem Code aus dem Quellcode. Mit einem Interpreter ist der Quellcode gelesen und wird interpretiert durch einen Interpreter , der dann den Code ausführt , wie es interpretiert. Ein Compiler hingegen liest den Quellcode und generiert aus dem Quellcode eine ausführbare Binärdatei - damit das Programm als separater Prozess unabhängig ausgeführt werden kann.

Bevor sich jemand wundert ... Ja, C / C ++ / C # / Java kann interpretiert werden, und ja, JavaScript- und Bash-Skripte können kompiliert werden. Ob es für diese Sprachen Dolmetscher oder Compiler gibt, ist eine andere Frage.

Um nun die Frage zu beantworten, wann wir "interpretierte Sprache" anstelle von "kompilierter Sprache" verwenden. Die Frage selbst ist etwas verwirrend, aber ich gehe davon aus, dass es bedeutet, wann die Interpretation der Zusammenstellung vorzuziehen ist. Einer der Nachteile der Kompilierung besteht darin, dass aufgrund des Kompilierungsprozesses ein gewisser Overhead entsteht. Der Quellcode muss zu ausführbarem Maschinencode kompiliert werden, sodass er nicht für Aufgaben geeignet ist, die beim Aufrufen des Quellcodes zum Ausführen eines Programms nur eine minimale Verzögerung erfordern . Andererseits ist kompilierter Quellcode aufgrund des durch die Interpretation des Codes verursachten Overheads fast immer schneller als gleichwertig interpretierter Quellcode. Dolmetscher hingegen können den Quellcode aufrufen und ausführen mit sehr geringem Aufrufaufwand, jedoch auf Kosten der Laufzeitleistung.

Am Ende ist es nahezu unmöglich, bestimmte Anwendungsfälle zu erwähnen, wenn einer nach dem anderen bevorzugt werden soll, aber zum Beispiel wäre ein (meiner Meinung nach sehr unrealistischer) Fall, wenn sich der Programmquellcode zwischen Programmaufrufen dynamisch ändert und der Aufwand für das Kompilieren ebenfalls ist hoch, damit es eine tragfähige Wahl ist. In diesem Fall wäre es wahrscheinlich wünschenswert, den Quellcode zu interpretieren, anstatt ihn zu kompilieren.

Es gibt jedoch etwas, das als reales Beispiel angesehen werden kann: Verstecken des Quellcodes bei der Bereitstellung. Mit nativkompilierter Code Der Entwickler stellt den ausführbaren Macine-Code des Programms und der Daten bereit. Bei interpretiertem Code muss der Quellcode selbst bereitgestellt werden, der dann mit viel weniger Aufwand überprüft und rückentwickelt werden kann als bei der Rückentwicklung von nativem Maschinencode. Eine Ausnahme bilden Sprachen wie C # und Java, die zu sofortiger Sprache / Bytecode kompiliert werden (MSIL für C # und Java-Bytecode für Java), die dann zur Laufzeit "just in time" bereitgestellt und kompiliert werden, ähnlich wie es ein Interpreter tut. Es gibt jedoch sogenannte Dekompilierer für MSIL und Java Bytecode, die den ursprünglichen Quellcode mit relativ guter Genauigkeit rekonstruieren können. Daher ist das Reverse Engineering solcher Produkte weitaus trivialer als das Reverse Engineering von Produkten, die im nativen Maschinencode eingesetzt werden.

zxcdw
quelle
1
Sie machen gute Punkte, aber da ich der Pedant bin, habe ich Probleme mit einigen Formulierungen (beide beziehen sich auf den dritten Absatz): 1. Ein Dolmetscher kompiliert nicht. 2. Es ist unergründlich (obwohl diese Bedingungen selten sind), dass ein schlechter, nicht optimierender Compiler von einem hochoptimierten (insbesondere bytecodebasierten) Interpreter geschlagen wird. Dies geht doppelt, wenn Sie JIT-Compiler unter Interpreten zählen (was ich lieber nicht mache, aber einige Leute machen das).
@delnan Vielleicht ist es schlecht formuliert, ich bin kein englischer Muttersprachler. Soweit ich das beurteilen kann, bedeutet der dritte Absatz jedoch nicht, dass ein Dolmetscher kompilieren würde. Für den zweiten Punkt betrifft , habe ich betont , auf das Wort äquivalent zu Betonung Ähnlichkeit von kompilierten und interpretierten Code , die Fälle von schlechter Compiler vs. High-Performance - Interpreter auszuschließen, vielleicht war ich nicht mit ihm ist klar, aber ich sehe es nicht Es ist vernünftig, sich auf die Erklärung solcher Extremfälle zu konzentrieren, da dies nichts dazu beiträgt, zwischen den Unterschieden bei der Ausführung des Quellcodes durch Kompilieren oder Iterpressen einen Unterschied zu machen
zxcdw
Entschuldigung, egal, der erste Punkt, ich habe etwas falsch verstanden. Mea culpa. Was den zweiten Punkt betrifft: Ich habe "Äquivalent" verwendet, um auf den Code zu verweisen, der interpretiert oder kompiliert wird (und ein Vergleich von Compiler und Interpreter macht nicht viel Sinn, da sie grundlegend unterschiedliche Dinge tun). Ich denke nicht, dass man Zeit damit verschwenden sollte, ausgefallene Fälle wie mein Beispiel zu beschreiben, aber ich würde es vorziehen, das "Immer" zugunsten einer Formulierung zu streichen, die erklärt, warum es überhaupt schneller sein kann : Kein Dolmetscher-Overhead [was sein sollte definiert IMHO] und die Möglichkeit, Optimierungen vor der Laufzeit durchzuführen.
1

Ich kann mir die folgenden Szenarien vorstellen, wenn Sie eine interpretierte Sprache verwenden würden:

  • Wo kein Compiler vorhanden ist, wie Linux / Unix- Shell-Skripte .
  • Schnelle und schmutzige Skripte, die ein kleines Problem lösen
  • Sprachen, die das Schreiben dynamischer HTML-Seiten vereinfachen und allgemein interpretiert werden, sind JSP (Tomcat kompiliert es zu einem Servler, das zuvor ausgeführt werden soll), PHP, ASP usw.

Ich kann mir die folgenden Szenarien vorstellen, wenn Sie Ihren Code kompilieren möchten :

  • Sie müssen Binärdateien verteilen, da Ihre App Closed-Source ist und Sie Ihren Quellcode nicht weitergeben möchten.
  • Geschwindigkeit, wie eingebettete Systeme und dergleichen.
  • Sie benötigen ein Maß an Sicherheit für Codetypen , das nur ein Compiler mit einer streng typisierten Sprache bieten kann. Compiler legen Tippfehler in jeder Ecke Ihres Quellcodes offen, während Tippfehler in interpretierten Programmen im Produktionscode unentdeckt bleiben können.
  • Große , komplexe Systeme: Sie können sich ein Betriebssystem oder einen Büroanzug nur als kompilierte Binärdateien vorstellen.
  • Sie möchten jeden kleinen Aufwand aus dem Weg räumen und benötigen eine gute Kommunikation mit Assembler-Snippets (schwierig mit jeder Art von Laufzeit, insbesondere mit einem Interpreter) (dieser Punkt wird durch einen @ delnam-Kommentar verursacht).
Tulains Córdova
quelle
3
Ein Sprachdolmetscher macht die Sprache nicht weniger stark typisiert. Haskell ist extrem stark typisiert und Sie können GHCI verwenden, um es effektiv zu interpretieren. Starke / schwache Typisierung sind Aspekte einer Sprache, keine Aspekte eines Compilers oder Interpreters.
Jimmy Hoffa
1
-1 Zu den Kompilierungsprofis: (1) Das Kompilieren von Code schützt nicht vor Reverse Engineering, sondern macht es nur etwas schwieriger. (2) Die Kompilierung (Beseitigung des Interpreter-Overheads, automatisierte Optimierung des Anwendungscodes) ist nur eine Leistungsquelle und wird durch handgefertigte groß angelegte Optimierungen durch einen menschlichen Experten übertroffen. (3) Die Typprüfung ist zwar normalerweise mit der Kompilierung verbunden, jedoch unabhängig davon. Eine Typprüfung ist ein statischer Analysedurchlauf. Dies kann ohne Ausgabe von Code und vor der Interpretation des Codes geschehen. (4) Scheint ziemlich falsch. Sie können sich das nicht vorstellen? Warum? Wie ist es erforderlich?
1
Andere interpretierte Sprachen existieren immer dann, wenn sich in einem anderen Programm ein Dolmetscher befindet. Immer wenn man das Interpreter-Muster verwendet , gibt es eine interpretierte Sprache von einiger Komplexität.
3
"Skripte" werden nicht unbedingt interpretiert. Viele "Skriptsprachen" werden zu Bytecode für eine virtuelle Maschine kompiliert , die dann ausgeführt wird (siehe lua, perl, python, ruby). Es gibt keinen wirklichen Unterschied zwischen diesem und Java, außer wenn die Kompilierung stattfindet.
3
+1, ich denke, das ist die Art von Antwort, nach der das OP wirklich gesucht hat, und obwohl die Punkte, wie bereits erwähnt, möglicherweise nicht zu 100% zutreffen, gibt es aus praktischen Gründen mindestens 95%.
Doc Brown
1

Am Ende besteht der große Kompromiss zwischen Produktivität (wie viele Codezeilen müssen Sie schreiben) und Leistung (wie schnell wird Ihr Programm ausgeführt).

Da interpretierte Sprachen bei der Umwandlung in CPU-Informationen mehr Informationen enthalten, können sie sich auf Reflexion und dynamische Typisierung verlassen, was die Produktivität erheblich steigert . Ein weiterer Vorteil interpretierter Sprachen besteht darin, dass sie plattformunabhängig sind, solange ein Interpreter für die Plattform vorhanden ist.

Da die CPU den Sprachcode nicht in Maschinencode umwandeln und den Code gleichzeitig ausführen darf, wie im interpretierten Fall, ergeben kompilierte Sprachen schnellere Programme. Außerdem ist ein in einer kompilierten Sprache erstelltes System sicherer, da es beim Kompilieren Probleme erkennen kann. Dies bedeutet im Grunde, dass Sie beim Eingeben einen Fehler sehen (mit modernen IDEs), anstatt ihn nur zu sehen, wenn Sie das Programm tatsächlich ausführen (natürlich) , dies behebt keine logischen Fehler).

In diesem Wissen eignen sich interpretierte Sprachen für:

  1. Produktive Entwicklung: schnelle Webentwicklung (PHP, Javascript) oder für das Prototyping.
  2. Plattformübergreifend; Beispielsweise wird JavaScript in jedem Browser (einschließlich mobiler Browser) unterstützt.

Und kompilierte Sprachen eignen sich, wenn:

  1. Die Leistung ist kritisch (Betriebssysteme) oder die Ressourcen sind knapp (Mikrocontroller).
  2. Zu bauende Systeme sind komplex; Beim Erstellen großer Systeme (Unternehmenssysteme) sind kompilierte Sprachen unerlässlich, um viele mögliche Fehler zu behandeln, die in interpretierten Sprachen auftreten können. Auch komplexe Programme erfordern viele Ressourcen und das Gleichgewicht tendiert dazu, auch Sprachen zu kompilieren.
m3th0dman
quelle
-1, weil Sie implizieren, dass alle interpretierten Sprachen dynamisch und alle kompilierten Sprachen statisch typisiert sind, was völlig falsch ist.
Daniel Pryden
@ DanielPryden Es muss also reiner Zufall sein, dass fast alle interpretierten Sprachen dynamisch typisiert und die kompilierten statisch typisiert werden? Ist es ein Zufall, dass das dynamische Typmodell für interpretierte Sprachen geeignet ist?
m3th0dman
Aus verschiedenen Gründen besteht eine Korrelation, die jedoch nicht erforderlich ist. Dies wurde bei StackOverflow
Daniel Pryden
1
Erlang wird kompiliert und dynamisch typisiert. Haskell ist statisch typisiert und kann kompiliert oder interpretiert werden
Zachary K
1
@ZacharyK Erlang hat ein Laufzeitsystem; Haskell wird in den meisten Fällen kompiliert (Programme geschrieben).
m3th0dman
1

Neben den von den anderen genannten Gründen gibt es einen besonders wichtigen Anwendungsfall für die Auswahl einer Ad-hoc-Interpretation gegenüber jeder Form der Zusammenstellung oder einem hybriden Ansatz.

Wenn eine Programmiersprache als Kommunikationsprotokoll verwendet wird und die Antwortlatenz wichtig ist, ist es sinnvoller, keine Zeit für die Kompilierung und eine mögliche Vorverarbeitung zu verschwenden.

Dies gilt beispielsweise für Agentensprachen oder für die Art und Weise, wie beispielsweise Tcl / Tk normalerweise verwendet wird.

Ein weiterer möglicher Grund für das Festhalten an der Interpretation besteht darin, dass ein Sprachinterpreter zum Bootstrapping selbst oder für eine ausgefeiltere Sprache höherer Ebene verwendet wird und seine Einfachheit wichtiger ist als die Leistung des Bootstrap-Prozesses.

Für fast jeden anderen möglichen Anwendungsfall ist die Kompilierung (oder ein hybrider Ansatz) besser geeignet.

SK-Logik
quelle