Was ist der Unterschied zwischen kompilierter und interpretierter Sprache?

118

Nachdem ich Material zu diesem Thema gelesen habe, bin ich mir immer noch nicht sicher, was der Unterschied zwischen einer kompilierten und einer interpretierten Sprache ist. Mir wurde gesagt, dies sei einer der Unterschiede zwischen Java und JavaScript. Würde mir bitte jemand helfen, es zu verstehen?

SIr Codealot
quelle

Antworten:

165

Was ist der Unterschied zwischen kompilierter und interpretierter Sprache?

Der Unterschied liegt nicht in der Sprache; es ist in der Umsetzung .

Nachdem ich das aus meinem System herausgeholt habe, hier eine Antwort:

  • In einer kompilierten Implementierung wird das ursprüngliche Programm in native Maschinenanweisungen übersetzt, die direkt von der Hardware ausgeführt werden.

  • In einer interpretierten Implementierung wird das ursprüngliche Programm in etwas anderes übersetzt. Ein anderes Programm, "der Interpreter" genannt, untersucht dann "etwas anderes" und führt alle erforderlichen Aktionen aus. Abhängig von der Sprache und ihrer Implementierung gibt es verschiedene Formen von "etwas anderem". Von populärer zu weniger populär könnte "etwas anderes" sein

    • Binäre Anweisungen für eine virtuelle Maschine, die häufig als Bytecode bezeichnet wird , wie dies in Lua, Python, Ruby, Smalltalk und vielen anderen Systemen der Fall ist (der Ansatz wurde in den 1970er Jahren vom UCSD P-System und UCSD Pascal populär gemacht).

    • Eine baumartige Darstellung des ursprünglichen Programms, z. B. ein Baum mit abstrakter Syntax, wie er für viele Prototypen oder pädagogische Dolmetscher verwendet wird

    • Eine tokenisierte Darstellung des Quellprogramms, ähnlich wie bei Tcl

    • Die Zeichen des Quellprogramms, wie in MINT und TRAC

Eine Sache, die das Problem kompliziert, ist, dass es möglich ist, Bytecode in native Maschinenanweisungen zu übersetzen (zu kompilieren) . Daher kann eine erfolgreiche interpretierte Implementierung möglicherweise einen Compiler erhalten. Wenn der Compiler hinter den Kulissen dynamisch ausgeführt wird, wird er häufig als Just-in-Time-Compiler oder JIT-Compiler bezeichnet. JITs wurden für Java, JavaScript, Lua und viele andere Sprachen entwickelt. Zu diesem Zeitpunkt können Sie eine hybride Implementierung haben, in der ein Teil des Codes interpretiert und ein Teil des Codes kompiliert wird.

Norman Ramsey
quelle
7
Sir, ich habe folgende Fragen: 1. In welcher Sprache ist das "etwas anderes" geschrieben? 2. Und ist das im Kontext von JavaScript "etwas anderes" von Browser zu Browser unterschiedlich? 3. Angenommen, mein Skript wird in Google Chrome und Internet Explorer ausgeführt. Wird es in beiden Browsern gleich interpretiert?
JavaHopper
@ Norman das war eine tolle Erklärung. Hier sind jedoch einige Verwirrungen, die ich noch habe. In einer kompilierten Implementierung wird das ursprüngliche Programm in native Maschinenanweisungen konvertiert. Woher? Ich dachte zum Beispiel, dass C nach dem Kompilieren Assembler-Code erzeugen würde, der ohnehin von einem nativen Assembler in den Maschinencode des zugrunde liegenden Computers zusammengesetzt werden muss. Wie unterscheidet sich das von einer VM (Python oder JVM usw.), die bei einer interpretierten Sprache dasselbe tut?
qre0ct
58

Java und JavaScript sind ein ziemlich schlechtes Beispiel, um diesen Unterschied zu demonstrieren , da beide interpretierte Sprachen sind . Java (interpretiert) und C (oder C ++) (kompiliert) könnten ein besseres Beispiel gewesen sein.

Warum der durchgestrichene Text? Wie diese Antwort richtig zeigt, handelt es sich beim Interpretieren / Kompilieren um eine konkrete Implementierung einer Sprache, nicht um die Sprache an sich . Während Aussagen wie "C ist eine kompilierte Sprache" im Allgemeinen wahr sind, hindert nichts jemanden daran, einen C-Sprachinterpreter zu schreiben. In der Tat, Dolmetscher für C existieren .

Grundsätzlich kann kompilierter Code direkt von der CPU des Computers ausgeführt werden. Das heißt, der ausführbare Code wird in der "Muttersprache" der CPU ( Assemblersprache ) angegeben.

Der Code der interpretierten Sprachen muss jedoch zur Laufzeit von einem beliebigen Format in Anweisungen der CPU-Maschine übersetzt werden. Diese Übersetzung wird von einem Dolmetscher durchgeführt.

Eine andere Art, es auszudrücken, ist, dass interpretierte Sprachen Code sind, der Schritt für Schritt in Maschinenanweisungen übersetzt wird, während das Programm ausgeführt wird, während kompilierte Sprachen Code haben, dessen Code vor der Programmausführung übersetzt wurde .

stakx - nicht mehr beitragen
quelle
8
Java wird interpretiert? Aus Wikipedia: "Java-Anwendungen werden normalerweise zu Bytecode (Klassendatei) kompiliert, der unabhängig von der Computerarchitektur auf jeder Java Virtual Machine (JVM) ausgeführt werden kann."
Personman
6
@Personman, der technisch immer noch "interpretiert" wird, da die JVM den Code ausführt, nicht das Betriebssystem selbst. Es ist wirklich ein semantischer Unterschied mehr, da man sagen könnte, dass die Komplexität moderner Betriebssysteme den Unterschied für die meisten Situationen grundsätzlich irrelevant macht. Sie sprechen über den Unterschied zwischen dem Betriebssystem, auf dem die App ausgeführt wird, und dem Betriebssystem, auf dem eine App ausgeführt wird, auf der der Code ausgeführt wird.
GrayWizardx
5
Ich nehme an, Sie meinen, dass Klassendateien selbst von der Java-VM interpretiert werden. Das ist ziemlich vernünftig, aber die Java-Quelle ist wirklich zu Java VM-Bytecode kompiliert. Sie können eine physische Java-Maschine erstellen, bei der die VM nicht in den Maschinencode einer anderen Architektur interpretiert werden muss. Es scheint also genauer zu sein, zu sagen, dass Java kompiliert ist. Dies ist jedoch ein gutes Beispiel dafür, wie verwirrend und willkürlich die Unterscheidung ist. Immerhin wird kompiliertes C von der CPU interpretiert, oder?
Personman
13
Java ist ein ziemlich schlechtes Beispiel für eine kompilierte oder interpretierte Sprache, da es im Wesentlichen beides ist. Wenn ich einen Vergleich anstellen würde, würde ich mit C und Lisp gehen, um Verwirrung zu vermeiden.
Bill the Lizard
7
@stakx - Tatsächlich werden Java-Bytecodes normalerweise auch von einem JIT-Compiler zu nativem Code kompiliert. Die einzige Möglichkeit, ein reines Interpreter-Verhalten zu erzielen, besteht darin, den JIT-Compiler beim Start der JVM explizit auszuschalten.
Stephen C
15

Hier ist der grundlegende Unterschied zwischen Compiler- und Interpreter-Sprache.

Compilersprache

  • Nimmt das gesamte Programm als einzelne Eingabe und konvertiert es in Objektcode, der in der Datei gespeichert ist.
  • Zwischenobjektcode wird generiert
  • zB: C, C ++
  • Kompilierte Programme werden schneller ausgeführt, da die Kompilierung vor der Ausführung erfolgt.
  • Der Speicherbedarf ist eher auf die Erstellung von Objektcode zurückzuführen.
  • Fehler werden angezeigt, nachdem das gesamte Programm kompiliert wurde
  • Quellcode --- Compiler --- Maschinencode --- Ausgabe

Dolmetschersprache:

  • Nimmt eine einzelne Anweisung als einzelne Eingabe und führt Anweisungen aus.
  • Zwischenobjektcode wird NICHT generiert
  • zB: Perl, Python, Matlab
  • Interpretierte Programme werden langsamer ausgeführt, da Kompilierung und Ausführung gleichzeitig erfolgen.
  • Der Speicherbedarf ist geringer.
  • Fehler werden für jede einzelne Anweisung angezeigt.
  • Quellcode --- Interpreter --- Ausgabe
PGOEL
quelle
5

Ein Compiler liest im Allgemeinen Computercode einer höheren Sprache und konvertiert ihn entweder in P-Code oder in nativen Maschinencode. Ein Interpreter wird direkt aus p-Code oder einem interpretierten Code wie Basic oder Lisp ausgeführt. In der Regel wird kompilierter Code viel schneller ausgeführt, ist kompakter und hat bereits alle Syntaxfehler und viele der illegalen Referenzfehler gefunden. Interpretierter Code findet solche Fehler erst, nachdem die Anwendung versucht hat, den betroffenen Code zu interpretieren. Interpretierter Code eignet sich oft für einfache Anwendungen, die nur einmal oder höchstens ein paar Mal verwendet werden, oder sogar für das Prototyping. Kompilierter Code ist besser für ernsthafte Anwendungen. Ein Compiler nimmt zuerst das gesamte Programm auf, sucht nach Fehlern, kompiliert es und führt es dann aus. Während ein Interpreter dies Zeile für Zeile ausführt, benötigt er eine Zeile und prüft sie auf Fehler.

Wenn Sie weitere Informationen benötigen, suchen Sie bei Google nach "Unterschied zwischen Compiler und Interpreter".

Salil
quelle
3
Ähm, ich bin mir nicht sicher, woher Sie etwas davon haben, das über die ersten beiden Aussagen hinausgeht. Dies war vor einigen Generationen mit vielen interpretierten Sprachen technisch richtig, aber je nach Plattform und Liebe zum Detail ist es möglich, Code zu interpretieren, der für bestimmte Aktivitäten in der Nähe oder kompiliertem Code funktioniert.
GrayWizardx
Wenn man bedenkt, dass Sprachen wie Java, C # und JavaScript heute fast die gesamte Programmierwelt überfluten, ist es unfair zu sagen, dass "kompilierter Code für ernsthafte Anwendungen besser ist".
Sisir
2

Es ist eine sehr trübe Unterscheidung und im Allgemeinen keine Eigenschaft einer Sprache selbst, sondern des Programms, mit dem Sie Code in dieser Sprache ausführen.

Die meisten Sprachen werden jedoch hauptsächlich in der einen oder anderen Form verwendet, und ja, Java wird im Wesentlichen immer kompiliert, während Javascript im Wesentlichen immer interpretiert wird.

Um den Quellcode zu kompilieren, müssen Sie ein Programm darauf ausführen, das eine binäre, ausführbare Datei generiert, die beim Ausführen das von der Quelle definierte Verhalten aufweist. Zum Beispiel kompiliert javac von Menschen gelesene Java-Dateien in maschinenlesbare Klassendateien.

Um den Quellcode zu interpretieren, wird ein Programm darauf ausgeführt, das das definierte Verhalten sofort erzeugt, ohne eine Zwischendatei zu generieren. Wenn Ihr Webbrowser beispielsweise stackoverflow.com lädt, interpretiert er eine Reihe von Javascript (die Sie durch Anzeigen der Seitenquelle anzeigen können) und erzeugt viele der netten Effekte, die diese Seiten haben - zum Beispiel Upvoting oder den kleinen Notifier Balken auf der Oberseite.

Personman
quelle
Während Java zuerst in Bytecode übersetzt und nur während der Ausführung der JVM in Maschinencode konvertiert wird; Ist es richtig zu sagen, dass es kompiliert und nicht interpretiert wird?
Sisir
1
Man kann wohl sagen, dass Java-Bytecode interpretiert wird, aber niemand schreibt Java-Bytecode. Java selbst wird normalerweise zu Bytecode kompiliert.
Personman
2

Die interpretierte Sprache wird zur Laufzeit gemäß den Anweisungen wie in Shell-Skripten ausgeführt, und die kompilierte Sprache wird kompiliert (in Assemblersprache geändert, die die CPU verstehen kann) und dann wie in c ++ ausgeführt.

Praveen Kishor
quelle
0

Wie andere gesagt haben, sind kompiliert und interpretiert spezifisch für eine Implementierung einer Programmiersprache; Sie sind der Sprache nicht inhärent. Zum Beispiel gibt es C-Interpreter.

Wir können (und in der Praxis auch) Programmiersprachen anhand ihrer häufigsten (manchmal kanonischen) Implementierung klassifizieren. Zum Beispiel sagen wir, dass C kompiliert ist.

Zunächst müssen wir ohne Mehrdeutigkeit Interpreter und Compiler definieren:

Ein Interpreter für Sprache X ist ein Programm (oder eine Maschine oder nur eine Art von Mechanismus im Allgemeinen), das jedes in Sprache X geschriebene Programm p so ausführt, dass es die Effekte ausführt und die Ergebnisse gemäß der Spezifikation von X bewertet .

Ein Compiler von X nach Y ist ein Programm (oder eine Maschine oder nur eine Art Mechanismus im Allgemeinen), das jedes Programm p aus einer Sprache X in ein semantisch äquivalentes Programm p ' in einer Sprache Y so übersetzt, dass p interpretiert wird ' mit einem Interpreter für Y die gleichen Ergebnisse erzielen und haben die gleichen Wirkungen wie die Interpretation p mit einem Interpreter für X .

Beachten Sie, dass CPUs aus Sicht des Programmierers Maschinendolmetscher für ihre jeweilige native Maschinensprache sind.

Jetzt können wir eine vorläufige Klassifizierung der Programmiersprachen in drei Kategorien vornehmen, abhängig von der häufigsten Implementierung:

  • Hart kompilierte Sprachen: Wenn die Programme vollständig in Maschinensprache kompiliert sind. Der einzige verwendete Interpreter ist eine CPU. Beispiel: Um ein Programm in C auszuführen, wird der Quellcode normalerweise in die Maschinensprache kompiliert, die dann von einer CPU ausgeführt wird.
  • Interpretierte Sprachen: Wenn kein Teil des Originalprogramms in Maschinensprache kompiliert wurde. Mit anderen Worten, es wird kein neuer Maschinencode generiert. Es wird nur vorhandener Maschinencode ausgeführt. Es muss auch ein anderer Interpreter als die CPU verwendet werden (normalerweise ein Programm). Beispiel: Bei der kanonischen Implementierung von Python wird der Quellcode zuerst in Python-Bytecode kompiliert und dann wird dieser Bytecode von CPython ausgeführt, einem Interpreterprogramm für Python-Bytecode .
  • Soft Compiled Languages: Wenn ein anderer Interpreter als die CPU verwendet wird, aber auch Teile des Originalprogramms in Maschinensprache kompiliert werden können. Dies ist der Fall bei Java, wo der Quellcode zuerst zu Bytecode kompiliert wird und dann der Bytecode vom Java-Interpreter interpretiert und / oder vom JIT-Compiler weiter kompiliert werden kann.

Manchmal werden weiche und harte kompilierte Sprachen als einfach kompiliert bezeichnet, daher wird C #, Java, C, C ++ als kompiliert bezeichnet.

Innerhalb dieser Kategorisierung war JavaScript eine interpretierte Sprache, aber das war vor vielen Jahren. Heutzutage ist es in den meisten wichtigen JavaScript-Implementierungen JIT-kompiliert in die native Maschinensprache, daher würde ich sagen, dass es in weich kompilierte Sprachen fällt.

MrIo
quelle