Ich versuche, den Unterschied besser zu verstehen. Ich habe online viele Erklärungen gefunden, aber sie tendieren eher zu den abstrakten Unterschieden als zu den praktischen Implikationen.
Die meisten meiner Programmiererfahrungen habe ich mit CPython (dynamisch, interpretiert) und Java (statisch, kompiliert) gemacht. Ich verstehe jedoch, dass es andere Arten von interpretierten und kompilierten Sprachen gibt. Gibt es neben der Tatsache, dass ausführbare Dateien aus Programmen verteilt werden können, die in kompilierten Sprachen geschrieben sind, Vor- und Nachteile für jeden Typ? Oft höre ich Leute argumentieren, dass interpretierte Sprachen interaktiv verwendet werden können, aber ich glaube, dass kompilierte Sprachen auch interaktive Implementierungen haben können, richtig?
Antworten:
Eine kompilierte Sprache ist eine Sprache, in der das einmal kompilierte Programm in den Anweisungen des Zielcomputers ausgedrückt wird. Beispielsweise könnte eine zusätzliche "+" - Operation in Ihrem Quellcode direkt in die Anweisung "ADD" im Maschinencode übersetzt werden.
Eine interpretierte Sprache ist ein , wo die Anweisungen nicht direkt von der Zielmaschine ausgeführt, sondern gelesen und durch ein anderes Programm ausgeführt (die in der Regel ist in der Sprache der nativen Maschinen geschrieben). Zum Beispiel würde der Interpreter zur Laufzeit dieselbe "+" - Operation erkennen, die dann seine eigene Funktion "add (a, b)" mit den entsprechenden Argumenten aufruft und dann den Befehl "ADD" des Maschinencodes ausführt .
Sie können alles tun, was Sie in einer interpretierten Sprache in einer kompilierten Sprache tun können und umgekehrt - beide sind vollständig. Beide haben jedoch Vor- und Nachteile für die Implementierung und Verwendung.
Ich werde es vollständig verallgemeinern (Puristen verzeihen mir!), Aber ungefähr hier sind die Vorteile kompilierter Sprachen:
Und hier sind die Vorteile interpretierter Sprachen:
Beachten Sie, dass moderne Techniken wie die Bytecode-Kompilierung eine zusätzliche Komplexität verursachen. Was hier passiert, ist, dass der Compiler auf eine "virtuelle Maschine" abzielt, die nicht mit der zugrunde liegenden Hardware identisch ist. Diese Anweisungen für virtuelle Maschinen können dann zu einem späteren Zeitpunkt erneut kompiliert werden, um nativen Code abzurufen (z. B. wie vom Java JVM JIT-Compiler ausgeführt).
quelle
Eine Sprache selbst wird weder kompiliert noch interpretiert, sondern nur eine bestimmte Implementierung einer Sprache. Java ist ein perfektes Beispiel. Es gibt eine Bytecode-basierte Plattform (JVM), einen nativen Compiler (gcj) und einen Interpeter für eine Obermenge von Java (bsh). Was ist Java jetzt? Bytecode-kompiliert, nativ kompiliert oder interpretiert?
Andere Sprachen, die sowohl kompiliert als auch interpretiert werden, sind Scala, Haskell oder Ocaml. Jede dieser Sprachen verfügt über einen interaktiven Interpreter sowie einen Compiler für Bytecode oder nativen Maschinencode.
Eine allgemeine Kategorisierung von Sprachen nach "kompiliert" und "interpretiert" macht daher wenig Sinn.
quelle
Fangen Sie an, in einer Explosion aus der Vergangenheit zu denken
Es war einmal vor langer, langer Zeit, als im Land der Computerinterpreten und Compiler lebte. Es kam zu allerlei Aufhebens um die Verdienste des einen über das andere. Die allgemeine Meinung zu dieser Zeit war etwas in der Art von:
Zwischen einem interpretierten Programm und einem kompilierten Programm bestand ein Unterschied von ein oder zwei Größenordnungen in der Laufzeitleistung. Andere Unterscheidungsmerkmale, beispielsweise die Laufzeitveränderlichkeit des Codes, waren ebenfalls von Interesse, aber die Hauptunterscheidung drehte sich um die Laufzeitleistungsprobleme.
Heute hat sich die Landschaft so weit entwickelt, dass die zusammengestellte / interpretierte Unterscheidung so gut wie irrelevant ist. Viele kompilierte Sprachen rufen Laufzeitdienste auf, die nicht vollständig auf Maschinencode basieren. Außerdem werden die meisten interpretierten Sprachen vor der Ausführung in Bytecode "kompiliert". Bytecode-Interpreter können unter dem Gesichtspunkt der Ausführungsgeschwindigkeit sehr effizient sein und mit einigen vom Compiler generierten Codes konkurrieren.
Der klassische Unterschied besteht darin, dass Compiler nativen Maschinencode generieren, Interpreter Quellcode lesen und Maschinencode im laufenden Betrieb mithilfe eines Laufzeitsystems generieren. Heutzutage gibt es nur noch wenige klassische Interpreter - fast alle kompilieren in Bytecode (oder einen anderen halbkompilierten Zustand), der dann auf einer virtuellen "Maschine" ausgeführt wird.
quelle
Die extremen und einfachen Fälle:
Ein Compiler erstellt eine ausführbare Binärdatei im nativen ausführbaren Format des Zielcomputers. Diese Binärdatei enthält alle erforderlichen Ressourcen mit Ausnahme der Systembibliotheken. Es kann ohne weitere Vorbereitung und Verarbeitung ausgeführt werden und läuft wie ein Blitz, da der Code der native Code für die CPU auf dem Zielcomputer ist.
Ein Dolmetscher zeigt dem Benutzer eine Eingabeaufforderung in einer Schleife an, in die er Anweisungen oder Code eingeben kann, und beim Schlagen
RUN
oder Äquivalent wird der Dolmetscher jede Zeile untersuchen, scannen, analysieren und interpretativ ausführen, bis das Programm zu einem Haltepunkt oder einem Fehler läuft . Da jede Zeile für sich behandelt wird und der Dolmetscher nichts "lernt", wenn er die Zeile zuvor gesehen hat, fällt jedes Mal für jede Zeile der Aufwand an, eine für Menschen lesbare Sprache in Maschinenanweisungen umzuwandeln, sodass der Hund langsam ist. Auf der positiven Seite kann der Benutzer sein Programm auf verschiedene Arten überprüfen und auf andere Weise mit ihm interagieren: Ändern von Variablen, Ändern von Code, Ausführen im Trace- oder Debug-Modus ... was auch immer.Lassen Sie mich erklären, dass das Leben nicht mehr so einfach ist. Zum Beispiel,
Letztendlich ist das Interpretieren gegenüber dem Kompilieren heutzutage ein Kompromiss, da die (einmalige) Kompilierungszeit häufig durch eine bessere Laufzeitleistung belohnt wird, aber eine interpretative Umgebung, die mehr Interaktionsmöglichkeiten bietet. Beim Kompilieren und Dolmetschen geht es hauptsächlich darum, wie die Arbeit zum "Verstehen" des Programms auf verschiedene Prozesse aufgeteilt wird, und die Linie ist heutzutage etwas verschwommen, da Sprachen und Produkte versuchen, das Beste aus beiden Welten anzubieten.
quelle
Von http://www.quora.com/Was ist der Unterschied zwischen kompilierten und interpretierten Programmiersprachen?
quelle
Der größte Vorteil des interpretierten Quellcodes gegenüber dem kompilierten Quellcode ist die PORTABILITÄT .
Wenn Ihr Quellcode kompiliert ist, müssen Sie für jeden Prozessortyp und / oder jede Plattform, auf der Ihr Programm ausgeführt werden soll, eine andere ausführbare Datei kompilieren (z. B. eine für Windows x86, eine für Windows x64, eine für Linux x64 usw.) auf). Sofern Ihr Code nicht vollständig standardkonform ist und keine plattformspezifischen Funktionen / Bibliotheken verwendet, müssen Sie tatsächlich mehrere Codebasen schreiben und verwalten!
Wenn Ihr Quellcode interpretiert wird, müssen Sie ihn nur einmal schreiben und er kann von einem geeigneten Interpreter auf jeder Plattform interpretiert und ausgeführt werden! Es ist tragbar ! Beachten Sie, dass ein Interpreter selbst ein ausführbares Programm ist , das für eine bestimmte Plattform geschrieben und kompiliert wurde.
Ein Vorteil von kompiliertem Code besteht darin, dass er den Quellcode vor dem Endbenutzer verbirgt (was möglicherweise geistiges Eigentum ist ), da Sie anstelle der Bereitstellung des ursprünglichen, für Menschen lesbaren Quellcodes eine undurchsichtige ausführbare Binärdatei bereitstellen.
quelle
Ein Compiler und ein Interpreter erledigen die gleiche Aufgabe: Sie übersetzen eine Programmiersprache in eine andere Pgoramming-Sprache, die normalerweise näher an der Hardware liegt, und leiten häufig ausführbaren Maschinencode.
Traditionell bedeutet "kompiliert", dass diese Übersetzung auf einmal erfolgt, von einem Entwickler durchgeführt wird und die resultierende ausführbare Datei an Benutzer verteilt wird. Reines Beispiel: C ++. Die Kompilierung dauert normalerweise ziemlich lange und versucht, viele teure Optimierungen vorzunehmen, damit die resultierende ausführbare Datei schneller ausgeführt wird. Endbenutzer verfügen nicht über die Tools und das Wissen, um Inhalte selbst zu kompilieren, und die ausführbare Datei muss häufig auf einer Vielzahl von Hardware ausgeführt werden, sodass Sie nicht viele hardwarespezifische Optimierungen vornehmen können. Während der Entwicklung bedeutet der separate Kompilierungsschritt einen längeren Rückkopplungszyklus.
Traditionell bedeutet "interpretiert", dass die Übersetzung "on the fly" erfolgt, wenn der Benutzer das Programm ausführen möchte. Reines Beispiel: Vanille PHP. Ein naiver Interpreter muss jedes Stück Code bei jeder Ausführung analysieren und übersetzen, was es sehr langsam macht. Es können keine komplexen, kostspieligen Optimierungen durchgeführt werden, da diese länger dauern würden als die bei der Ausführung eingesparte Zeit. Es kann jedoch die Funktionen der Hardware, auf der es ausgeführt wird, voll nutzen. Das Fehlen eines separaten Kompilierungsschritts reduziert die Rückkopplungszeit während der Entwicklung.
Aber heutzutage ist "kompiliert vs. interpretiert" kein Schwarz-Weiß-Thema, dazwischen gibt es Schattierungen. Naive, einfache Dolmetscher sind so gut wie ausgestorben. Viele Sprachen verwenden einen zweistufigen Prozess, bei dem der Code auf hoher Ebene in einen plattformunabhängigen Bytecode übersetzt wird (der viel schneller zu interpretieren ist). Dann haben Sie "Just-in-Time-Compiler", die Code höchstens einmal pro Programmlauf kompilieren, manchmal Ergebnisse zwischenspeichern und sogar intelligent entscheiden, selten ausgeführten Code zu interpretieren und leistungsstarke Optimierungen für häufig ausgeführten Code vorzunehmen. Während der Entwicklung können Debugger den Code innerhalb eines laufenden Programms auch für traditionell kompilierte Sprachen wechseln.
quelle
Zunächst einmal ist Java nicht vollständig statisch kompiliert und wie C ++ verknüpft. Es wird in Bytecode kompiliert, der dann von einer JVM interpretiert wird. Die JVM kann eine Just-in-Time-Kompilierung in die native Maschinensprache durchführen, muss dies jedoch nicht.
Mehr auf den Punkt gebracht: Ich denke, Interaktivität ist der wichtigste praktische Unterschied. Da alles interpretiert wird, können Sie einen kleinen Auszug aus Code nehmen, analysieren und gegen den aktuellen Status der Umgebung ausführen. Wenn Sie also bereits Code ausgeführt hätten, der eine Variable initialisiert hat, hätten Sie Zugriff auf diese Variable usw. Es eignet sich wirklich für Dinge wie den Funktionsstil.
Die Interpretation kostet jedoch viel, insbesondere wenn Sie ein großes System mit vielen Referenzen und Kontexten haben. Per Definition ist dies verschwenderisch, da identischer Code möglicherweise zweimal interpretiert und optimiert werden muss (obwohl die meisten Laufzeiten dafür zwischengespeichert und optimiert sind). Trotzdem zahlen Sie Laufzeitkosten und benötigen häufig eine Laufzeitumgebung. Es ist auch weniger wahrscheinlich, dass komplexe interprozedurale Optimierungen auftreten, da deren Leistung derzeit nicht ausreichend interaktiv ist.
Daher ist es für große Systeme, die sich nicht wesentlich ändern werden, und für bestimmte Sprachen sinnvoller, alles vorkompilieren und vorab zu verknüpfen und alle Optimierungen vorzunehmen, die Sie vornehmen können. Dies führt zu einer sehr schlanken Laufzeit, die bereits für den Zielcomputer optimiert ist.
Was das Generieren von Executbles betrifft, hat das meiner Meinung nach wenig damit zu tun. Sie können häufig eine ausführbare Datei aus einer kompilierten Sprache erstellen. Sie können aber auch eine ausführbare Datei aus einer interpretierten Sprache erstellen, mit der Ausnahme, dass der Interpreter und die Laufzeit bereits in der ausführbaren Datei gepackt und vor Ihnen verborgen sind. Dies bedeutet, dass Sie im Allgemeinen immer noch die Laufzeitkosten bezahlen (obwohl ich sicher bin, dass es für einige Sprachen Möglichkeiten gibt, alles in eine ausführbare Baumdatei zu übersetzen).
Ich bin nicht der Meinung, dass alle Sprachen interaktiv gemacht werden könnten. Bestimmte Sprachen wie C sind so stark an die Maschine und die gesamte Linkstruktur gebunden, dass ich nicht sicher bin, ob Sie eine aussagekräftige, vollwertige interaktive Version erstellen können
quelle
Es ist ziemlich schwierig, eine praktische Antwort zu geben, da der Unterschied in der Sprachdefinition selbst liegt. Es ist möglich, einen Interpreter für jede kompilierte Sprache zu erstellen, aber es ist nicht möglich, einen Compiler für jede interpretierte Sprache zu erstellen. Es geht sehr um die formale Definition einer Sprache. Damit theoretische Informatik-Sachen, die Noboby an der Universität mag.
quelle
Das Python-Buch © 2015 Imagine Publishing Ltd unterscheidet den Unterschied einfach durch den folgenden Hinweis, der auf Seite 10 erwähnt wird:
quelle
Beim Kompilieren wird ein ausführbares Programm aus Code erstellt, der in einer kompilierten Programmiersprache geschrieben ist. Durch das Kompilieren kann der Computer das Programm ausführen und verstehen, ohne dass die zum Erstellen verwendete Programmiersoftware erforderlich ist. Wenn ein Programm kompiliert wird, wird es häufig für eine bestimmte Plattform (z. B. IBM Plattform) kompiliert, die mit IBM kompatiblen Computern funktioniert, jedoch nicht für andere Plattformen (z. B. Apple Plattform). Der erste Compiler wurde von Grace Hopper während der Arbeit am Harvard Mark I-Computer entwickelt. Heutzutage enthalten die meisten Hochsprachen einen eigenen Compiler oder Toolkits, mit denen das Programm kompiliert werden kann. Ein gutes Beispiel für einen mit Java verwendeten Compiler ist Eclipse, und ein Beispiel für einen mit C und C ++ verwendeten Compiler ist der Befehl gcc.
quelle
Kurze (ungenaue) Definition:
Kompilierte Sprache: Das gesamte Programm wird sofort in Maschinencode übersetzt, dann wird der Maschinencode von der CPU ausgeführt.
Interpretierte Sprache: Das Programm wird zeilenweise gelesen, und sobald eine Zeile gelesen wird, werden die Maschinenanweisungen für diese Zeile von der CPU ausgeführt.
Aber wirklich, heutzutage werden nur wenige Sprachen rein kompiliert oder interpretiert, es ist oft eine Mischung. Eine detailliertere Beschreibung mit Bildern finden Sie in diesem Thread:
Was ist der Unterschied zwischen Zusammenstellung und Interpretation?
Oder mein späterer Blogbeitrag:
https://orangejuiceliberationfront.com/the-difference-between-compiler-and-interpreter/
quelle