Wenn Sie sich Julias Webseite ansehen , sehen Sie einige Benchmarks mehrerer Sprachen über mehrere Algorithmen (Timings siehe unten). Wie kann eine Sprache mit einem Compiler, der ursprünglich in C geschrieben wurde, C-Code übertreffen?
Abbildung: Benchmark-Zeiten im Verhältnis zu C (kleiner ist besser, C-Leistung = 1,0).
programming-languages
compilers
efficiency
StrugglingProgrammer
quelle
quelle
Antworten:
Es besteht kein notwendiger Zusammenhang zwischen der Implementierung des Compilers und der Ausgabe des Compilers. Sie könnten einen Compiler in einer Sprache wie Python oder Ruby, deren häufigste Implementierungen sind sehr langsam, schreiben und dass Compiler könnte Ausgang hochMaschinenCode optimiert Lage , übertraf damit C. Der Compiler selbst eine lange Zeit zu laufen dauern würde, weil ihreCode ist in einer langsamen Sprache geschrieben. (Genauer gesagt, in einer Sprache mit langsamer Implementierung geschrieben. Sprachen sind nicht von Natur aus schnell oder langsam, wie Raphael in einem Kommentar ausführt. Ich werde auf diese Idee weiter unten eingehen.) Das kompilierte Programm wäre so schnell wie es ist Eigene Implementierung erlaubt - wir könnten einen Compiler in Python schreiben, der den gleichen Maschinencode wie ein Fortran-Compiler generiert, und unsere kompilierten Programme wären so schnell wie Fortran, auch wenn die Kompilierung viel Zeit in Anspruch nimmt.
Es ist eine andere Geschichte, wenn wir über einen Dolmetscher sprechen. Dolmetscher müssen ausgeführt werden, während das Programm, das sie interpretieren, ausgeführt wird. Daher besteht ein Zusammenhang zwischen der Sprache, in der der Dolmetscher implementiert ist, und der Leistung des interpretierten Codes. Es ist eine clevere Laufzeitoptimierung erforderlich, um eine interpretierte Sprache zu erstellen, die schneller ausgeführt wird als die Sprache, in der der Interpreter implementiert ist. Die endgültige Leistung kann davon abhängen, wie gut ein Codeteil für diese Art der Optimierung geeignet ist. Viele Sprachen, wie Java und C #, verwenden Laufzeiten mit einem Hybridmodell, das einige der Vorteile von Interpreten mit einigen der Vorteile von Compilern kombiniert.
Schauen wir uns Python als konkretes Beispiel genauer an. Python hat mehrere Implementierungen. Am gebräuchlichsten ist CPython, ein in C geschriebener Bytecode-Interpreter. Es gibt auch PyPy, das in einem speziellen Python-Dialekt namens RPython geschrieben ist und ein hybrides Kompilierungsmodell ähnlich der JVM verwendet. PyPy ist in den meisten Benchmarks viel schneller als CPython. Es verwendet alle möglichen erstaunlichen Tricks, um den Code zur Laufzeit zu optimieren. Die Python-Sprache, die PyPy ausführt, entspricht jedoch genau der Python-Sprache , die CPython ausführt, mit Ausnahme einiger Unterschiede, die die Leistung nicht beeinträchtigen.
Angenommen, wir haben einen Compiler in der Python-Sprache für Fortran geschrieben. Unser Compiler erzeugt den gleichen Maschinencode wie GFortran. Jetzt kompilieren wir ein Fortran-Programm. Wir können unseren Compiler auf CPython oder PyPy ausführen, da er in Python geschrieben ist und beide Implementierungen dieselbe Python-Sprache ausführen. Wir werden feststellen, dass, wenn wir unseren Compiler auf CPython ausführen, ihn dann auf PyPy ausführen und dann dieselbe Fortran-Quelle mit GFortran kompilieren, wir alle drei Male genau denselben Maschinencode erhalten, sodass das kompilierte Programm immer ausgeführt wird mit etwa der gleichen Geschwindigkeit. Die für die Erstellung dieses kompilierten Programms erforderliche Zeit ist jedoch unterschiedlich. CPython wird höchstwahrscheinlich länger dauern als PyPy, und PyPy wird höchstwahrscheinlich länger dauern als GFortran, obwohl alle am Ende denselben Maschinencode ausgeben.
Beim Durchsuchen der Benchmark-Tabelle der Julia-Website sieht es so aus, als ob keine der auf Dolmetschern (Python, R, Matlab / Octave, Javascript) ausgeführten Sprachen Benchmarks hat, bei denen sie C schlagen. obwohl ich mir vorstellen könnte, dass Code mit Pythons hochoptimierter Numpy-Bibliothek (geschrieben in C und Fortran) einige mögliche C-Implementierungen von ähnlichem Code übertrifft. Die Sprachen, die gleich oder besser als C sind, werden kompiliert (Fortran, Julia ) oder mit einem Hybridmodell mit teilweiser Kompilierung (Java und wahrscheinlich LuaJIT). PyPy verwendet auch ein Hybridmodell. Wenn wir also auf PyPy anstelle von CPython denselben Python-Code ausführen, ist es durchaus möglich, dass er bei einigen Benchmarks C übertrifft.
quelle
Wie kann eine von einem Menschen gebaute Maschine stärker sein als ein Mensch? Das ist genau die gleiche Frage.
Die Antwort ist, dass die Ausgabe des Compilers von den von diesem Compiler implementierten Algorithmen abhängt und nicht von der Sprache, in der er implementiert wurde. Sie könnten einen sehr langsamen, ineffizienten Compiler schreiben, der sehr effizienten Code erzeugt. Ein Compiler hat nichts Besonderes: Er ist nur ein Programm, das Eingaben macht und Ausgaben erzeugt.
quelle
Ich möchte einen Punkt gegen eine verbreitete Annahme aussprechen, die meiner Meinung nach so trügerisch ist, dass sie bei der Auswahl der Werkzeuge für einen Job schädlich ist.
Es gibt keine langsame oder schnelle Sprache. ¹
Auf dem Weg zur CPU gibt es tatsächlich einige Schritte².
Jedes einzelne Element trägt zur tatsächlichen Laufzeit bei, die Sie manchmal stark messen können. Unterschiedliche "Sprachen" konzentrieren sich auf unterschiedliche Dinge³.
Nur um einige Beispiele zu nennen.
1 vs 2-4 : Ein durchschnittlicher C-Programmierer erzeugt wahrscheinlich weitaus schlechteren Code als ein durchschnittlicher Java-Programmierer, sowohl in Bezug auf Korrektheit als auch Effizienz. Das liegt daran, dass der Programmierer mehr Verantwortung in C hat.
1/4 vs 7 : In einer einfachen Sprache wie C können Sie möglicherweise bestimmte CPU-Funktionen als Programmierer ausnutzen . In höheren Sprachen kann dies nur der Compiler / Interpreter und nur dann, wenn er die Ziel-CPU kennt .
1/4 vs 5 : Möchten oder müssen Sie das Speicherlayout steuern, um die vorhandene Speicherarchitektur optimal zu nutzen? Einige Sprachen geben Ihnen die Kontrolle darüber, andere nicht.
2/4 vs 3 : Ausgelegt Python selbst ist schrecklich langsam, aber es gibt beliebte Bindungen zu hoch optimierten, nativ kompilierten Bibliotheken für wissenschaftliches Rechnen. Bestimmte Dinge in Python zu tun ist also am Ende schnell , wenn die meiste Arbeit von diesen Bibliotheken erledigt wird.
2 gegen 4 : Der Standard-Ruby-Interpreter ist ziemlich langsam. JRuby hingegen kann sehr schnell sein. Das ist die gleiche Sprache ist schnell mit einem anderen Compiler / Interpreter.
1/2 vs 4 : Mit Hilfe von Compiler-Optimierungen kann einfacher Code in sehr effizienten Maschinencode übersetzt werden.
Die Quintessenz ist, dass der von Ihnen gefundene Benchmark wenig Sinn macht, zumindest nicht, wenn er auf die von Ihnen angegebene Tabelle reduziert wird. Auch wenn Sie nur an der Laufzeit interessiert sind, müssen Sie die gesamte Kette vom Programmierer bis zur CPU angeben . Das Austauschen eines der Elemente kann die Ergebnisse dramatisch verändern.
Um es klar auszudrücken, hiermit wird die Frage beantwortet, da die Sprache, in der der Compiler (Schritt 4) geschrieben ist, nur ein Teil des Puzzles ist und wahrscheinlich überhaupt nicht relevant ist (siehe andere Antworten).
Ich gehe hier bewusst nicht auf verschiedene Erfolgsmetriken ein: Laufzeiteffizienz, Speichereffizienz, Entwicklerzeit, Sicherheit, (nachweisbare?) Korrektheit, Tool-Unterstützung, Plattformunabhängigkeit, ...
Der Vergleich von Sprachen mit einer Metrik, obwohl sie für ganz andere Ziele entwickelt wurden, ist ein großer Irrtum.
quelle
Es gibt eine vergessene Sache bei der Optimierung.
Es gab eine lange Debatte darüber, ob Fortran C übertreffen sollte. Eine missgebildete Debatte wurde auseinander genommen: Der gleiche Code wurde in C geschrieben und Fortran (wie die Tester dachten) und die Leistung wurde basierend auf den gleichen Daten getestet. Das Problem ist, dass diese Sprachen unterschiedlich sind. C erlaubt das Aliasing von Zeigern, während fortran dies nicht tut.
Die Codes waren also nicht gleich, es gab keine Einschränkung in C-getesteten Dateien, was zu Unterschieden führte, nachdem Dateien neu geschrieben wurden, um dem Compiler mitzuteilen, dass Zeiger optimiert werden können, und die Laufzeiten sich ähnelten.
Der Punkt hier ist, dass einige Optimierungstechniken in neu erstellter Sprache einfacher (oder legaler) sind.
Auf lange Sicht ist es auch möglich, VMs mit JIT-Outperform C zuX
erstellen . Es gibt zwei Möglichkeiten: JIT-Code kann den Vorteil der Maschine nutzen, auf der er ausgeführt wird (z. B. einige SSE oder andere, für einige CPU-vektorisierte Anweisungen exklusive Befehle), die nicht implementiert wurden Programm verglichen.
Zweitens kann VM während der Ausführung einen Drucktest durchführen, um unter Druck stehenden Code zu erfassen und zu optimieren oder sogar während der Laufzeit vorzukalkulieren. Im Voraus kompiliertes C-Programm erwartet nicht, wo der Druck ist oder (meistens) es gibt generische Versionen von ausführbaren Dateien für die allgemeine Maschinenfamilie.
In diesem Test gibt es auch JS, also gibt es schnellere VMs als V8, und in einigen Tests ist es auch schneller als C.
Ich habe es überprüft und es gab einzigartige Optimierungstechniken, die in C-Compilern noch nicht verfügbar waren.
C-Compiler müsste sofort eine statische Analyse des gesamten Codes durchführen, auf einer bestimmten Plattform marschieren und Probleme mit der Speicherausrichtung umgehen.
VM hat nur einen Teil des Codes transliteriert, um die Assembly zu optimieren und auszuführen.
Über Julia - als ich überprüfte, dass es auf AST von Code funktioniert, hat GCC diesen Schritt übersprungen und gerade erst begonnen, einige Informationen von dort zu übernehmen. Dies und andere Einschränkungen und VM-Techniken könnten ein wenig erklären.
Beispiel: Nehmen wir eine einfache Schleife, die den Start- und Endpunkt von Variablen übernimmt und einen Teil der Variablen zur Laufzeit in die bekannten Berechnungen lädt.
Der C-Compiler generiert Ladevariablen aus Registern.
Aber zur Laufzeit sind diese Variablen bekannt und werden durch die Ausführung als Konstanten behandelt.
Anstatt also Variablen aus Registern zu laden (und keine Zwischenspeicherung durchzuführen, weil sie sich ändern können, und aus statischen Analysen nicht klar ist, werden sie vollständig wie Konstanten behandelt und gefaltet, weitergegeben.
quelle
Die vorangegangenen Antworten geben so ziemlich die Erklärung, wenn auch meistens aus einem pragmatischen Blickwinkel, denn so sehr die Frage Sinn macht , wie es Raphaels Antwort vortrefflich erklärt .
Ergänzend zu dieser Antwort sollten wir beachten, dass C-Compiler heutzutage in C geschrieben sind. Natürlich können, wie Raphael bemerkt, ihre Ausgabe und ihre Leistung unter anderem von der CPU abhängen, auf der sie ausgeführt wird. Es kommt aber auch auf den Optimierungsgrad des Compilers an. Wenn Sie in C einen besser optimierenden Compiler für C schreiben (den Sie dann mit dem alten kompilieren, um ihn ausführen zu können), erhalten Sie einen neuen Compiler, der C zu einer schnelleren Sprache macht als zuvor. Also, was ist die Geschwindigkeit von C? Beachten Sie, dass Sie den neuen Compiler sogar in einem zweiten Durchgang mit sich selbst kompilieren können, so dass er effizienter kompiliert wird, obwohl Sie immer noch denselben Objektcode angeben. Und der Vollbeschäftigungssatz zeigt, dass solche Verbesserungen kein Ende haben (danke an Raphael für den Hinweis).
Ich denke jedoch, dass es sich lohnen kann, das Problem zu formalisieren, da es einige grundlegende Konzepte und insbesondere die denotationale und die operationelle Sichtweise der Dinge sehr gut illustriert.
Was ist ein Compiler?
Ein Compiler , abgekürzt mit wenn keine Mehrdeutigkeit vorliegt, ist eine Realisierung einer berechenbaren Funktion , die einen Programmtext eine Funktion berechnet , in einer geschriebenen Quellsprache in den Programmtext in einer schriftlichen Zielsprache , wird das soll die gleiche Funktion berechnen .CS→T C CS→T P:S P S P:T T P
Aus semantischer Sicht, dh denotational , spielt es keine Rolle, wie diese Kompilierfunktion berechnet wird, dh welche Realisierung gewählt wird. Es könnte sogar durch ein magisches Orakel geschehen. Mathematisch ist die Funktion einfach eine Menge von Paaren .CS→T CS→T {(P:S,P:T)∣PS∈S∧PT∈T}
Die semantische Kompilierungsfunktion ist korrekt, wenn sowohl als auch dieselbe Funktion berechnen . Diese Formalisierung gilt jedoch auch für einen inkorrekten Compiler. Der einzige Punkt ist, dass alles, was implementiert wird, unabhängig von den Implementierungsmitteln das gleiche Ergebnis erzielt. Was semantisch zählt, ist, was vom Compiler gemacht wird, nicht wie (und wie schnell) es gemacht wird.CS→T PS PT P
Tatsächlich ist das Erhalten von von ein operationelles Problem, das gelöst werden muss. Aus diesem Grund muss die Kompilierungsfunktion eine berechenbare Funktion sein. Dann kann jede Sprache mit Turing-Power, egal wie langsam sie ist, Code so effizient produzieren wie jede andere Sprache, auch wenn dies möglicherweise weniger effizient ist.P:T P:S CS→T
Wenn wir das Argument verfeinern, möchten wir wahrscheinlich, dass der Compiler eine gute Effizienz aufweist, damit die Übersetzung in angemessener Zeit ausgeführt werden kann. Die Leistung des Compiler-Programms ist also für die Benutzer von Bedeutung, hat jedoch keinen Einfluss auf die Semantik. Ich sage Leistung, weil die theoretische Komplexität einiger Compiler viel höher sein kann, als man erwarten würde.
Über Bootstrapping
Dies wird die Unterscheidung veranschaulichen und eine praktische Anwendung zeigen.
Es ist nun üblich, zuerst eine Sprache mit einem Interpreter zu implementieren und dann einen Compiler in der Sprache selbst zu schreiben . Dieser Compiler kann mit dem Interpreter , um ein beliebiges Programm in ein Programm . Wir haben also einen laufenden Compiler von Sprache bis (Maschine?) Sprache , aber er ist sehr langsam, wenn auch nur, weil er auf einem Interpreter läuft.I S C S → TS IS S C S → TCS→T:S S I S P : S P : T STCS→T:S IS P:S P:T S T
Aber man kann diese Compilieren Anlage verwenden Sie den Compiler zu kompilieren , da es in der Sprache geschrieben ist , und somit erhalten Sie einen Compiler geschrieben in die Zielsprache . Wenn Sie, wie so oft, davon ausgehen, dass eine Sprache ist, die effizienter interpretiert wird (z. B. maschinenneutral), erhalten Sie eine schnellere Version Ihres Compilers, die direkt in der Sprache . Es erledigt genau den gleichen Job (dh es produziert die gleichen Zielprogramme), aber es erledigt es effizienter. S C S → TCS→T:S S TTTCS→T:T T T T
quelle
Nach dem Speedup-Theorem von Blum gibt es Programme, die auf der schnellsten Computer / Compiler-Kombination geschrieben und ausgeführt werden, die auf Ihrem ersten PC, auf dem interpretiertes BASIC ausgeführt wird, langsamer als ein entsprechendes Programm ausgeführt wird. Es gibt einfach keine "schnellste Sprache". Alles, was Sie sagen können, ist, dass, wenn Sie denselben Algorithmus in mehreren Sprachen schreiben (Implementierungen; wie bereits erwähnt, gibt es viele verschiedene C-Compiler, und ich bin sogar auf einen ziemlich fähigen C-Interpreter gestoßen), dieser in jedem schneller oder langsamer läuft .
Es kann keine "immer langsamere" Hierarchie geben. Dies ist ein Phänomen, das allen bekannt ist, die mehrere Sprachen fließend beherrschen: Jede Programmiersprache wurde für einen bestimmten Anwendungstyp entwickelt, und die am häufigsten verwendeten Implementierungen wurden liebevoll für diesen Programmtyp optimiert. Ich bin mir ziemlich sicher, dass z. B. ein Programm zum Herumalbern mit in Perl geschriebenen Zeichenfolgen wahrscheinlich den gleichen Algorithmus wie C übertreffen wird, während ein Programm, das in großen Arrays von Ganzzahlen in C kaut, schneller ist als Perl.
quelle
Kehren wir zur ursprünglichen Zeile zurück: "Wie kann eine Sprache, deren Compiler in C geschrieben ist, jemals schneller sein als C?" Ich denke, das bedeutete wirklich zu sagen: Wie kann ein in Julia geschriebenes Programm, dessen Kern in C geschrieben ist, jemals schneller sein als ein in C geschriebenes Programm? Wie kann das in Julia geschriebene Programm "mandel" in 87% der Ausführungszeit des in C geschriebenen entsprechenden Programms "mandel" ausgeführt werden?
Babous Abhandlung ist die einzig richtige Antwort auf diese Frage. Alle anderen Antworten beantworten mehr oder weniger andere Fragen. Das Problem mit Babous Text ist, dass die viele Absätze lange theoretische Beschreibung von "Was ist ein Compiler?" So geschrieben ist, dass das Originalplakat wahrscheinlich Probleme mit dem Verständnis hat. Wer die Begriffe "semantisch", "denotational", "verwirklichend", "berechenbar" usw. versteht, kennt die Antwort auf die Frage bereits.
Die einfachere Antwort ist, dass weder C-Code noch Julia-Code direkt von der Maschine ausgeführt werden können. Beide müssen übersetzt werden, und dieser Übersetzungsprozess bietet viele Möglichkeiten, wie der ausführbare Maschinencode langsamer oder schneller sein kann, aber dennoch das gleiche Endergebnis liefert. Sowohl C als auch Julia kompilieren, was eine Reihe von Übersetzungen in eine andere Form bedeutet. Im Allgemeinen wird eine für Menschen lesbare Textdatei in eine interne Darstellung übersetzt und dann als Folge von Anweisungen ausgegeben, die der Computer direkt verstehen kann. Bei einigen Sprachen steckt mehr dahinter, und Julia ist eine davon - sie hat einen "JIT" -Compiler, was bedeutet, dass der gesamte Übersetzungsprozess nicht für das gesamte Programm auf einmal stattfinden muss. Aber das Endergebnis für jede Sprache ist Maschinencode, der keine weitere Übersetzung benötigt. Code, der direkt an die CPU gesendet werden kann, damit er etwas tut. Am Ende ist DIES die "Berechnung", und es gibt mehr als eine Möglichkeit, einer CPU mitzuteilen, wie sie die gewünschte Antwort erhält.
Man kann sich eine Programmiersprache vorstellen, die sowohl einen "Plus" - als auch einen "Multiplikations" -Operator und eine andere Sprache, die nur "Plus" hat. Wenn für Ihre Berechnung eine Multiplikation erforderlich ist, ist eine Sprache "langsamer", da die CPU natürlich beide Funktionen direkt ausführen kann. Wenn Sie jedoch keine Möglichkeit haben, die Notwendigkeit der Multiplikation von 5 * 5 auszudrücken, müssen Sie nur noch "5" schreiben + 5 + 5 + 5 + 5 ". Letzteres wird mehr Zeit in Anspruch nehmen, um die gleiche Antwort zu erhalten. Vermutlich ist etwas davon mit Julia los; Vielleicht erlaubt die Sprache dem Programmierer, das gewünschte Ziel der Berechnung eines Mandelbrot-Satzes auf eine Weise anzugeben, die nicht direkt in C ausgedrückt werden kann.
Der für den Benchmark verwendete Prozessor wurde als Xeon E7-8850 2.00GHz-CPU aufgeführt. Der C-Benchmark verwendete den gcc 4.8.2-Compiler, um Anweisungen für diese CPU zu erstellen, während Julia das LLVM-Compiler-Framework verwendet. Es ist möglich, dass das Backend von gcc (der Teil, der Maschinencode für eine bestimmte CPU-Architektur erzeugt) nicht so weit fortgeschritten ist wie das LLVM-Backend. Das könnte die Leistung verbessern. Es gibt noch viele andere Dinge: Der Compiler kann "optimieren", indem er Anweisungen in einer anderen als der vom Programmierer festgelegten Reihenfolge ausgibt oder einige Dinge überhaupt nicht ausführt, wenn er den Code analysieren und feststellen kann, dass dies nicht der Fall ist erforderlich, um die richtige Antwort zu erhalten. Und der Programmierer hat vielleicht einen Teil des C-Programms auf eine Weise geschrieben, die es langsam macht, aber er hat es nicht getan.
All dies sind Möglichkeiten zu sagen: Es gibt viele Möglichkeiten, Maschinencode für die Berechnung eines Mandelbrot-Satzes zu schreiben, und die von Ihnen verwendete Sprache hat einen großen Einfluss darauf, wie dieser Maschinencode geschrieben wird. Je besser Sie sich mit Kompilierung, Anweisungssätzen, Caches usw. auskennen, desto besser können Sie die gewünschten Ergebnisse erzielen. Die wichtigste Erkenntnis aus den für Julia angegebenen Benchmark-Ergebnissen ist, dass keine Sprache oder kein Tool in allem die besten Ergebnisse erzielt. Tatsächlich war der beste Geschwindigkeitsfaktor im gesamten Diagramm für Java!
quelle
Die Geschwindigkeit eines kompilierten Programms hängt von zwei Dingen ab:
Die Sprache, in der ein Compiler geschrieben ist, ist für (1) irrelevant. Zum Beispiel kann ein Java-Compiler in C oder Java oder Python geschrieben werden, aber in allen Fällen ist die "Maschine", die das Programm ausführt, die JVM.
Die Sprache, in der ein Compiler geschrieben ist, ist für (2) irrelevant. Es gibt beispielsweise keinen Grund, warum ein in Python geschriebener C-Compiler nicht genau dieselbe ausführbare Datei wie ein in C oder Java geschriebener C-Compiler ausgeben kann.
quelle
Ich werde versuchen, eine kürzere Antwort anzubieten.
Der Kern der Frage liegt in der Definition der "Geschwindigkeit" einer Sprache .
Die meisten, wenn nicht alle Geschwindigkeitsvergleichstests testen nicht die maximal mögliche Geschwindigkeit. Stattdessen schreiben sie ein kleines Programm in einer Sprache, die sie testen möchten, um ein Problem zu lösen. Beim Schreiben des Programms verwendet der Programmierer zum Zeitpunkt des Tests das, was er als Best Practice und Konventionen der Sprache ansieht. Dann messen sie die Geschwindigkeit, mit der das Programm ausgeführt wurde.
* Die Annahmen sind gelegentlich falsch.
quelle
Code, der in einer Sprache X geschrieben ist, deren Compiler in C geschrieben ist, kann einen in C geschriebenen Code übertreffen, vorausgesetzt, der C-Compiler führt im Vergleich zu dem der Sprache X eine schlechte Optimierung durch Objektcode als der vom C-Compiler generierte, dann kann auch in X geschriebener Code das Rennen gewinnen.
Wenn jedoch die Sprache X eine interpretierte Sprache ist und der Interpreter in C geschrieben ist und wir annehmen, dass der Interpreter der Sprache X und des in C geschriebenen Codes von demselben C-Compiler kompiliert wird, wird der in X geschriebene Code in keiner Weise den Code übertreffen geschrieben in C, vorausgesetzt beide Implementierungen folgen demselben Algorithmus und verwenden äquivalente Datenstrukturen.
quelle