Compiler/Interpreter

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Lenni
User
Beiträge: 1
Registriert: Samstag 27. Juli 2013, 22:00

Hallo liebe Community,

ich beschäftige mich nun schon seit einiger Zeit mit Python als meine erste Programmiersprache. Da ich es relativ sinnlos fand programmieren zu lernen, ohne zu verstehen wie ein Computer arbeitet, beschäftige ich mich momentan mit ein paar Grundlagen der Computerwissenschaft. Da bin ich aber jetzt auf eine Frage gestoßen, die ich mir bisher nicht selbst erklären kann. Die Frage bezieht sich auf Compiler und Interpreter. Ich verstehe nicht so ganz, warum eine Computersprache entweder das eine oder das andere haben/ sein muss. Den Unterschied der beiden habe ich so verstanden:

Interpreter:
Übersetzt jede Zeile einzeln in den Maschinencode.

Compiler:
Übersetzt das ganze programmierte Programm in Maschinencode und lässt es dann laufen.

Warum kann eine interpreted language nicht einfach den übersetzten Maschinencode abspeichern? Diese Maschinencode kann dann wie bei dem eines Compiler ohne den Interpreter ausgeführt werden. So wäre doch der Nachteil der niedrigen Geschwindigkeit aufgehoben.
Genauso andersrum: warum kann ich eine compiled language nicht während der Entwicklung mit einen Interpreter laufen lassen, um besser Debuggen zu können und am Schluss alles durch den Compler schicken?

Ist es ein Gesetz der Computerwissenschaft, dass eine Programmiersprache nur eins der beiden benutzen darf?

Ich hoffe, dass meine Frage nicht allzu naiv ist (:

Liebe Grüße!
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Hallo Lenni und Willkommen im Forum!

Da hast Du eine Menge interessante Fragen und Schlussfolgerungen.

Über ähnliches ist hier schon oft diskutiert worden; da kannst Du über die SuFu einiges finden. ich würde mal nach "Python compilieren" o.ä. suchen.

Grundsätzlich ist der Unterschied zwischen Compiler und Interpreter ziemlich unscharf. Zumindfest wird da oftmals das eine mit dem anderen vermischt. Python selber wird nicht erst zur Laufzeit Zeile für Zeile eingelesen und interpretiert, sondern der Quellcode wird beim Starten des Programms über den Interpreter (z.B. python.exe) in Bytecode compiliert und dieser wird dann ausgeführt. Im Java-Umfeld spricht man da von "virtueller Maschine" - nichts anderes ist der Python-Interpreter. Konzeptionell gibt es da keinen (kaum?) einen Unterschied zu Code, der direkt auf dem Prozessor läuft. Bei Java spricht man dennoch vom Java-Compiler (javac), den man dann auf der virtuellen Maschine (java) ausführt. Bei Python sind beide Schritte in einem Programm vereint (python) und man spricht von Interpreter.

Beim Thema Geschwindigkeit scheiden sich die Geister. Es gibt viele interessante Möglichkeiten Bytecode schnell zu interpretieren; JIT dürfte da ziemlich prominent sein. Im übrigen kommt es bei vielen Projekten, wenn nicht den meisten, eher auf die Entwicklungs-Zeit an - und da kommt es eben auf Komfort beim Tooling an (darauf bezieht sich wohl dein letzter Abschnitt), Portierbarkeit und auf die Ausdrucksstärke einer Sprache an. Python ist viel ausdrucksstärker als z.B. C - aufgrund dessen jedoch auch nicht nativ in Maschinencode übersetzbar. (d.h. man kann mit viel weniger Code das Problem formulieren)

Im übrigen machen in den letzten Jahren Projekte wie LLVM (und speziell Clang) von sich reden, die eben einen Ansatz verfolgen, nicht mehr direkt auf native Maschinenebene zu übersetzen. Gründe dafür gibt es viele; schnelles Feedback für IDEs und allgemein fürs Tooling rund ums Entwicklen sind wohl eine der stärksten Motivatoren. Dazu kommen dann noch Aspekte der Optimierungsmöglichkeiten usw.

Um kurz den Abschluss zu finden: Es gibt natürlich tatsächlich Interpreter, die wirklich Zeile für Zeile Code einlesen, übersetzen und dann ausführen. Viele (ältere) Basic-Dialekte handhaben das so, aber auch z.B. die unixoiden Shells.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@Lenni: Also erst einmal ist Dein Verständnis vom Begriff „Interpreter” falsch. Der übersetzt nichts nach Maschinencode, und er muss auch nicht zwingend Zeilenweise arbeiten. Ein Interpreter *interpretiert* eine bestimmte Darstellung eines Programms, das heisst er schaut sich das Stück für Stück an, und *macht* dann etwas was letztendlich die Semantik der Sprache umsetzt. Dabei entsteht kein Maschinencode, den man speichern könnte.

Interpreter und Compiler schliessen sich auch nicht gegenseitig aus. Es gibt halt nur am einen Ende des Spektrums Programmiersprachen für die man selten einen Interpreter in Aktion sieht, zum Beispiel C, was aber nicht heisst, dass es solche Interpreter nicht geben würde, und am anderen Ende so etwas wie Python, was so dynamisch ist, dass sich ein klassischer Compiler für „nativen” Maschinencode nicht wirklich lohnt, weil kaum Optimierungen vorgenommen werden können, ohne die Semantik der Sprache zu verändern. Auch einen solchen Compiler gibt es aber mit Cython (und dem etwas älteren Projekt Pyrex). Wenn man allerdings damit unveränderten Python-Code zu Maschinencode übersetzt, kommt am Ende in der Regel nur Code heraus der statt dynamisch Bytecodes zu Funktionsaufrufen zu „dispatchen”, diese Funktionausfrufe direkt macht. Was nicht wirklich einen grossen Gewinn darstellt. Darum kann man für Cython den Python-Code noch mit Konstrukten erweitern die dem Compiler mehr Möglichkeiten zum optimieren bieten. Beispielsweise C-Datentypen statt Python-Objekten.

Das Standardpython hat beides: Einen Compiler der den Quelltext in Bytecode übersetzt, und einen Interpreter, der diesen Bytecode dann abarbeitet.

Mit dem PyPy-Projekt und gewissermassen als Vorstufe bei Python 2.x dem `psyco`-Modul gibt es auch JIT-Compiler die aus dem Bytecode während der Ausführung je nach verwendeten Datentypen spezialisierte Maschinencode-Varianten erstellen und ausführen.

Zuguterletzt kann man auch den Prozessor als einen Interpreter ansehen, der den Maschinencode interpretiert, so ähnlich wie die CPython-VM den Bytecode interpretiert.

Ein Gesetz, dass es für eine Programmiersprache nur Compiler *oder* Interpreter geben darf, gibt es nicht. Hat es auch nie gegeben. Selbst für Maschinensprache gab es schon recht früh Interpreter (in Software), damit zum Beispiel die Programme auf der nächsten Grossrechnergeneration mit einem teilweise oder komplett anderen Befehlssatz trotzdem noch ausgeführt werden konnten.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

BlackJack hat geschrieben:Zuguterletzt kann man auch den Prozessor als einen Interpreter ansehen, der den Maschinencode interpretiert, so ähnlich wie die CPython-VM den Bytecode interpretiert.
Das geht sogar noch weiter, denn der Prozessor, zumindest im Fall von x86 interpretiert seinen Assembler, die eigentlichen Befehle sind der Microcode. Dieser kann auch aktualisiert werden, somit läuft auf der CPU eigentlich auch eine Art Software.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten