Warum ist Python langsamer als Java, aber schneller als PHP?

17

Ich habe viele Male verschiedene Benchmarks gesehen, die zeigen, wie viele Sprachen eine bestimmte Aufgabe erfüllen.

Diese Benchmarks zeigen immer, dass Python langsamer als Java und schneller als PHP ist, und ich frage mich, warum das so ist.

  • Java, Python und PHP werden in einer virtuellen Maschine ausgeführt
  • Alle drei Sprachen konvertieren ihre Programme in ihre benutzerdefinierten Bytecodes, die auf dem Betriebssystem ausgeführt werden
  • Sowohl Java als auch Python können ( .pycfür Python) "kompiliert" werden, aber das __main__Modul für Python wird nicht kompiliert

Python und PHP werden dynamisch und Java statisch geschrieben. Dies ist der Grund, warum Java schneller ist. Wenn ja, erläutern Sie bitte, wie sich dies auf die Geschwindigkeit auswirkt.

Und selbst wenn das Argument dynamic-vs-static richtig ist, erklärt dies nicht, warum PHP langsamer ist als Python - weil beide dynamische Sprachen sind.

Sie können hier und hier und hier einige Benchmarks sehen

Baumkodierer
quelle
In Bezug auf Python vs. PHP: Es handelt sich höchstwahrscheinlich nur um ein Qualitätsproblem bei der Implementierung.
Charles Salvia
8
@good_computer Die meisten Benchmarks sind sehr schlecht gemacht. Es gab eine andere kürzlich erschienene (ich glaube nicht, dass Sie verlinkt haben), bei der sich die meisten Leute beschwerten, dass die Sprache, die als "am schnellsten" bezeichnet wird, einfach den am besten optimierten Code hat. Dies geschieht normalerweise unbewusst durch jemanden, der mit den Sprachen, die als "langsam" eingestuft werden, nicht so vertraut ist, sodass er nicht merkt, dass er in denjenigen, die er als "schnell" befunden hat, besseren Code schreibt.
Izkata
@good_computer Mir scheint, Sie behaupten etwas, da Ihre Frage den Text " Immer diese Benchmarks zeigen, dass Python langsamer als Java und schneller als PHP ist " und " PHP ist langsamer als Python " enthält. Wenn Sie diese Anführungszeichen entfernen und die Frage als sprachunabhängig umformulieren, wird sie möglicherweise erneut geöffnet.
Briddums
Diese Frage ist sehr voreingenommen : (1) Bezugnahme auf nicht autorisierende Benchmarks, die mit sehr naivem, nicht optimiertem Code durchgeführt wurden, der von unerfahrenen Programmierern in Sprachen geschrieben wurde, die sie nicht beherrschen (wie in den jeweiligen Kommentarthreads beschrieben), und (2) die auf falschen Vorstellungen beruhen über interpretierte / Bytecode-Sprachen (PHP / Python werden interpretiert, Java ist bytecodiert, Python-Cache-Dateien sind abstrakte Syntaxbäume, kein Bytecode) und den Zustand der drei Sprachen (es gibt kompilierte Versionen von Python und PHP - Pythons sind ausgereifter und kompilierter PHP läuft jedoch Facebook)
ZJR

Antworten:

26

JVM-Code kann mithilfe eines einfachen (und schnellen) Ad-hoc-Compilers effizient JIT-kompiliert werden. Dasselbe wäre jedoch für PHP und Python aufgrund ihrer dynamischen Schreibweise außerordentlich schwierig. JVM übersetzt in einen relativ einfachen, systemeigenen Code, ähnlich dem, was ein C ++ - Compiler erzeugen würde, aber für die dynamischen Sprachen müssten Sie einen dynamischen Versand für buchstäblich alle grundlegenden Operationen und für alle Methodenaufrufe generieren. Dieser dynamische Versand ist der primäre Engpass für alle Sprachen dieser Art.

In einigen Fällen ist es möglich, den dynamischen Versand (sowie die virtuellen Aufrufe in Java) mithilfe eines viel komplizierteren JIT-Compilers für die Ablaufverfolgung zu eliminieren. Dieser Ansatz steckt noch in den Kinderschuhen und macht nicht zu viel von einer abstrakten Interpretation, und ein solcher Compiler verschluckt wahrscheinlich evalAufrufe (die für dynamische Sprachen sehr typisch sind).

Was den Unterschied zwischen Python und PHP betrifft, so ist letzteres von viel geringerer Qualität. Theoretisch könnte es schneller laufen, wird es aber nie.

SK-Logik
quelle
1
Warum ist JIT für dynamische Sprachen "außergewöhnlich" schwierig? Schauen Sie sich v8 oder TraceMonkey in der JavaScript-Welt an - dort funktioniert JIT einwandfrei.
Treecoder
6
@good_computer, Tracing-JITs sind deutlich komplexer als normale Ad-hoc-JITs und für statisch typisierte Sprachen sind sie immer noch viel langsamer als JITs. Eine ordnungsgemäße JIT-Verfolgung würde eine vollständige abstrakte Interpretation beinhalten und bei jedem evalAufruf ersticken .
SK-logic
2
Es gibt wahrscheinlich ungefähr hundert Ingenieure im HotSpot-Compiler-Team von Oracle, die sich über den "trivialen" Teil nicht einig sind :-)
Jörg W Mittag,
1
@ JörgWMittag, natürlich ist HotSpot nicht so einfach, es führt ein bisschen statische Analyse durch, es verwendet die Ergebnisse der Laufzeitprofilerstellung, aber es ist noch viel einfacher als eine ordnungsgemäße JIT-Ablaufverfolgung. Und ich würde sagen, HotSpot ist überkompliziert und seine Implementierung ist, um es höflich auszudrücken, ein bisschen zu ausführlich.
SK-logic
1
@Frank Shearar, eine Ad-hoc-JIT für eine dynamische Sprache, ist ebenso trivial wie für eine statisch typisierte Sprache (siehe beispielsweise LuaJIT). OTOH, ein effizientes JIT ist eine ganz andere Sache.
SK-logic
21

Es gibt ein allgemeines Problem bei dieser Frage, dass sie zu absolut ist. Es ist nicht wirklich sinnvoll zu sagen, "Sprache X ist schneller als Sprache Y". Eine Computersprache selbst ist nicht "schnell" oder "langsam", weil sie lediglich einen Algorithmus ausdrückt. Die eigentliche Frage sollte in der Größenordnung von "Warum ist die Implementierung von X1 der Sprache X schneller als die Implementierung von Y1 der Sprache Y für diese bestimmte Problemdomäne?"

Einige Geschwindigkeitsunterschiede werden sicherlich aus der Sprache selbst herausfallen, da bestimmte Sprachen bestimmte Domänen leichter implementieren können als andere. Aber vieles, was eine Implementierung schnell macht, ist nicht die Sprache. Zum Beispiel kann man nicht wirklich sagen "Python ist langsamer als Java", ohne zu überlegen, ob es sich um CPython, IronPython oder PyPy handelt. Dies gilt insbesondere für Sprachen, die eine VM verwenden, da die Geschwindigkeit direkt von der Qualität der VM abhängt.

Abgesehen davon arbeite ich mit einem System, das JIT auf unserem Gerät aus verschiedenen Gründen nicht mit einer sehr beliebten JavaScript-VM verwenden kann, die es normalerweise unterstützt. Dies bedeutet, dass unser JavaScript sehr viel langsamer läuft als auf einem PC mit einem ähnlichen Prozessor. Diese eine Änderung, die nicht direkt mit der Sprache selbst zusammenhängt, führt dazu, dass JavaScript für die Aufgaben, die uns wichtig sind, "ein paar Mal langsamer als C ++" ist und "Größenordnungen langsamer als C ++" ist.

Bedenken Sie auch, dass Sprachen sich in ihren Leistungsmerkmalen in einer Weise unterscheiden, die nicht direkt vergleichbar ist. Zu viele Benchmarks übersetzen ein Programm nur von Sprache A in Sprache B und berücksichtigen nicht, dass sich die Sprachen in den schnellen Funktionen unterscheiden. (Sie können dies in jedem vernünftigen Benchmark-Vergleich sehen, wie denjenigen, auf die Sie verweisen, da sie häufig Hinweise wie "Dankeschön an so-and-so, dass Sie mir gezeigt haben, wie man es in der Sprache Foo umsetzt.)

Nehmen Sie zum Beispiel diesen Java-Code:

for(int i=0;i<10;i++) {
    Object o = new Object;
    doSomething(o);
}

Es wäre verlockend, dies in C ++ "umzuschreiben" und die Laufzeiten zu vergleichen:

for(int i=0;i<10;i++) {
    Object *o = new Object;
    doSomething(o);
    delete(o);
}

Die Sache ist, jeder kompetente C ++ - Programmierer wird sofort erkennen, dass dies in C ++ nicht der schnellste Weg ist, etwas zu tun. Sie können die Dinge ganz einfach beschleunigen, indem Sie sie an C ++ anpassen:

for(int i=0;i<10;i++) {
    Object o;
    doSomething(&o);
}

Der Punkt ist nicht, dass C ++ schnell sein kann, aber anstatt Benchmarks zu schreiben, um Sprachen zu vergleichen, ist es wirklich sehr, sehr schwierig. Um es richtig zu machen, müssen Sie ein Experte in beiden Sprachen sein und in beiden Sprachen von Grund auf neu schreiben. Selbst dann können Sie leicht Bereiche erreichen, in denen sich eine Sprache für eine bestimmte Aufgabe auszeichnet. Zum Beispiel kann ich eine Version von Towers of Hanoi in C ++ schreiben, die auf jedem vernünftigen Compiler schneller als Java läuft. Ich kann das tun, indem ich im Wesentlichen betrüge, indem ich C ++ - Vorlagen verwende, die zur Kompilierungszeit ausgewertet wurden (http://forums.devshed.com/c-programming-42/c-towers-of-hanoi-using-templates-424148.html).

Der Punkt dort ist nicht, dass ich sagen könnte, dass "C ++ ist schneller als Java", weil mein Programm sofort zurückkehrte, während die Java-Version für Minuten lief (und hoffend, dass niemand bemerkte, dass mein Programm eine halbe Stunde brauchte, um zu bauen.) Der Punkt ist, dass dafür variieren schmalen Fall, C ++ ist schneller. In anderen engen Fällen könnte es umgekehrt sein. Es ist also nicht "C ++ ist schneller", sondern "C ++ ist schneller in Fällen, in denen Sie den Ausdruck zur Erstellungszeit mithilfe von Vorlagen auswerten können." Weniger befriedigend, aber wahr.

Geschwindigkeitsunterschiede in Sprachen betreffen hauptsächlich die Implementierung. Kompilierte Sprachen sind schneller als interpretierte Sprachen. Das Kompilieren in systemeigenen Code wird schneller sein als das Kompilieren in Bytecode. Dies hat weitaus mehr Auswirkungen als Fragen wie, ob die Sprache statisch typisiert ist oder nicht. Und natürlich werden gute Implementierungen schneller als schlechte sein.

Und vergessen Sie nicht, dass gute Programmierer schneller Code produzieren werden als schlechte Programmierer, oft in einem Ausmaß, das die Sprachunterschiede deutlich überwiegt.

Gort den Roboter
quelle
6

Dies hängt mit der Qualität des Compilers zusammen, der Compiler von Java wurde viel länger kontinuierlich optimiert, und die Optimierung ist wichtiger, da der gesamte Code für Java kompiliert wird. Ich bin mir nicht sicher, warum Python schneller ist als PHP, aber ich wette, das liegt am Einfluss von Google auf Python.

Ryathal
quelle
8
Warum wurde das abgelehnt? Genau das ist die Antwort: Leistung ist nur eine Frage des Forschungs- und Entwicklungsaufwands und damit letztendlich des Geldes. Die Unternehmen, die Java-Implementierungen produzieren, sind einfach reicher als diejenigen, die Python- oder PHP-Implementierungen produzieren. Das ist alles.
Jörg W Mittag
1
Außerdem bin ich mir ziemlich sicher, dass CPython-Optimierungen nicht akzeptiert werden, wenn sie den Code zu schwer lesbar machen und die Leistung nur geringfügig verbessern.
cgt
2
+ Jörg W Mittag: Ich bin anderer Meinung. Einige Sprachmerkmale können sehr schwer performant zu implementieren sein, daher machen sie die Erstellung einer effizienten Implementierung sehr schwierig oder nahezu unmöglich. Andererseits ist es trivial einfach, eine "effiziente" Implementierung der "Assembler" -Sprache zu erstellen.
user281377
@ammoQ Ich vermute, dass ein Großteil davon auf Typsysteme zurückzuführen ist, insbesondere auf die Fähigkeit, genau zu wissen, welchen Typ Sie haben und wie die genaue Semantik der zulässigen Operationen lautet. Dynamische Sprachen sind zwar flexibler, erschweren jedoch das Erstellen von Typprüfungen (und somit das Kompilieren von sicherem hyper-schnellem Code).
Donal Fellows
1
@DonalFellows Genau mein Gedanke. Je weniger zum Zeitpunkt der Kompilierung bekannt ist, desto mehr muss zur Laufzeit herausgefunden werden.
user281377
4

Warum Java am schnellsten ist:

Statisch eingegebenes + JIT compile + --server-Flag, um den laufenden Code aggressiv neu zu kompilieren.

Warum Python schneller ist als PHP:

Python ist zwar eine dynamische Sprache, sie ist jedoch immer noch stark typisiert. Dies bedeutet, dass die von Ihnen codierten Strukturen zur Laufzeitoptimierung in der Lage sind.

Warum PHP scheiße ist:

Es ist im Grunde Javascript auf dem Server (keine Multithreading-Unterstützung, total dynamisch, lose geschrieben).

Je mehr der Compiler über Ihren Code Bescheid weiß, desto besser kann er optimieren. Java ist vor und während der Ausführung vollständig optimierbar. Python ist während des Betriebs optimierbar und PHP ist schrecklich. Facebook transpiliert tatsächlich ihr PHP nach C, bevor es auf den Server gelangt.
https://developers.facebook.com/blog/post/2010/02/02/hiphop-for-php--move-fast/

Ajax
quelle
Eigentlich ist Javascript auf dem Server Node.JS und nach meinem Verständnis (obwohl ich das nicht begründen werde) übertrifft die V8-Engine PHP im Allgemeinen (obwohl wahrscheinlich nicht um eine Tonne). Außerdem sollten Sie erwähnen, dass Python auf native kompiliert werden kann (Wie ist seine Leistung im Vergleich zu Java?)
Jimmy Hoffa,
Ich habe Python noch nicht ausführlich genug verwendet, um Ihnen dabei zu helfen, aber ich kann sagen, dass NodeJs mit V8 native C-Erweiterungen unterstützen (obwohl das Überschreiten der JS / C-Grenze angeblich langsam ist). Außerdem kann es den JIT-Compiler von Google nutzen. .. Ich wäre nicht überrascht, wenn der Knoten schneller als Python und PHP ist. Hier ist ein Benchmark (wie die meisten fehlerhaft) blog.famzah.net/2010/07/01/… Beachten Sie, dass der Java langsamer aussah als JS, bis ein Kommentator auf unsere Fehler im Benchmark hinwies ... Nehmen Sie es also mit einer Körnung von Salz. :)
Ajax
Allerdings sind Node und PHP auch beide Singlethread-fähig, und wenn Sie keine Cluster-Proxys (wie Haproxy) einrichten möchten, würde ich in einer seriösen Produktionsumgebung keine davon berühren.
Ajax
1

Die Benchmarks sind eher verzerrt zugunsten einer umfangreichen mathematischen Programmierung.

Es ist nicht überraschend, dass Python ziemlich gut in komplexer Mathematik ist, wenn man bedenkt, wo und warum es zuerst geschrieben wurde .

PHP hingegen wurde entwickelt, um Webseiten zu bedienen. Es kann andere Dinge tun, aber Webseiten sind das, was es am besten kann und es ist auf einer Stufe oder besser als Java bei dieser Aufgabe.

James Anderson
quelle