Was blockiert Ruby, Python, um die Geschwindigkeit von Javascript V8 zu erreichen? [geschlossen]

261

Gibt es Ruby / Python-Funktionen, die die Implementierung von Optimierungen blockieren (z. B. Inline-Caching ), über die die V8-Engine verfügt?

Python wurde von Google-Mitarbeitern mitentwickelt und sollte daher nicht durch Softwarepatente blockiert werden.

Oder es geht eher um Ressourcen, die Google in das V8-Projekt gesteckt hat.

Greg Dan
quelle
6
Selbstbeobachtung und Überlastung der Bediener sind wahrscheinlich große Probleme, aber ich kenne JS nicht gut genug, um Ihnen eine echte Antwort zu geben. Das PyPy-Projekt ist wahrscheinlich Pythons beste Chance, JS-Geschwindigkeiten zu erreichen.
Ncoghlan
11
Haben Sie Beispiele, bei denen PyPy langsamer als V8 ist, mit Ausnahme des Shootouts in Computersprache, bei dem es sich um einen kompletten Blödsinn handelt (sehen Sie sich nur an, wie unterschiedlich die Inhalte in verschiedenen Sprachen implementiert sind). Oder ist es nur Googles Reality Distortion Field?
Fidschal
3
V8 ist Python nicht ganz gewachsen. Warten Sie, bis V8 die Javascript-Spezifikation 1.8 implementieren muss, um einen besseren Vergleich zu ermöglichen. Und an diesem Punkt bin ich sicher, dass jemand versuchen wird, PyPy anstelle von Javascript auf der V8-Engine zu implementieren.
Michael Dillon
14
Warum bist du dir so sicher, dass V8 schneller ist als Python oder Ruby? An was?
jcoffland
6
V8 ist absolut schneller als Python / Ruby. Führen Sie jede Art von Benchmark durch, die Sie möchten, vom einfachen Mikrobenchmark bis zu einer umfassenden realen Anwendung, die in beiden Umgebungen idiomatisch geschrieben ist. Für die meisten sprachlichen Operationen ist dies eine Größenordnung schneller (z. B. Dinge, die in Python nicht an C-Code delegiert werden).
Hejazzman

Antworten:

519

Was blockiert Ruby, Python, um die Geschwindigkeit von Javascript V8 zu erreichen?

Nichts.

Na gut: Geld. (Und Zeit, Leute, Ressourcen, aber wenn Sie Geld haben, können Sie diese kaufen.)

V8 verfügt über ein Team von brillanten, hochspezialisierten, erfahrenen (und damit hochbezahlten) Ingenieuren, die über jahrzehntelange Erfahrung (ich spreche individuell - insgesamt sind es eher Jahrhunderte) bei der Erstellung von Hochleistungsausführungen verfügen Engines für dynamische OO-Sprachen. Es sind im Grunde die gleichen Leute, die (unter anderem) auch die Sun HotSpot JVM erstellt haben.

Lars Bak, der leitende Entwickler, arbeitet seit 25 Jahren buchstäblich an VMs (und all diese VMs haben bis zu V8 geführt), was im Grunde sein gesamtes (berufliches) Leben ist. Einige der Leute, die Ruby-VMs schreiben, sind noch nicht einmal 25 Jahre alt.

Gibt es Ruby / Python-Funktionen, die die Implementierung von Optimierungen blockieren (z. B. Inline-Caching), über die die V8-Engine verfügt?

Da mindestens IronRuby, JRuby, MagLev, MacRuby und Rubinius entweder monomorphes (IronRuby) oder polymorphes Inline-Caching haben, lautet die Antwort offensichtlich nein.

Moderne Ruby-Implementierungen führen bereits zahlreiche Optimierungen durch. Beispielsweise ist Rubinius ' HashKlasse für bestimmte Operationen schneller als die von YARV. Das klingt nicht besonders aufregend, bis Sie feststellen, dass Rubinius ' HashKlasse in 100% reinem Ruby implementiert ist, während YARVs in 100% handoptimiertem C implementiert ist.

Zumindest in einigen Fällen kann Rubinius also besseren Code als GCC generieren!

Oder es geht eher um Ressourcen, die Google in das V8-Projekt gesteckt hat.

Ja. Nicht nur Google. Die Herkunft des V8-Quellcodes ist jetzt 25 Jahre alt. Die Leute, die an V8 arbeiten, haben auch die Self VM (bis heute eine der schnellsten dynamischen OO-Sprachausführungs-Engines, die jemals erstellt wurden), die Animorphic Smalltalk VM (bis heute eine der schnellsten Smalltalk-Ausführungs-Engines, die jemals erstellt wurden) und den HotSpot erstellt JVM (die schnellste JVM, die jemals erstellt wurde, wahrscheinlich die schnellste VM-Periode) und OOVM (eine der effizientesten Smalltalk-VMs, die jemals erstellt wurden).

Tatsächlich arbeitete Lars Bak, der Hauptentwickler von V8, an jedem einzelnen und einigen anderen.

Jörg W Mittag
quelle
1
Können wir Referenzliteratur zu "Angesichts der Tatsache, dass zumindest IronRuby, JRuby, MagLev, MacRuby und Rubinius entweder monomorphes (IronRuby) oder polymorphes Inline-Caching haben, lautet die Antwort offensichtlich nein." Bitte?
WDRust
14
SpiderMonkey hat eine vergleichbare Leistung. Wie hat Mozilla das damals gemacht? Sie haben sehr begrenztes Geld ..
Salman von Abbas
8
@SalmanPK: Es ist nicht ihre erste VM, und es gibt auch kluge Leute, die bei Mozilla arbeiten.
Matthieu M.
3
@SalmanPK, miguel: Mozilla hat seine JS-VM zumindest teilweise durch Reverse Engineering V8 erstellt. blog.mozilla.org/dmandelin/2010/09/08/presenting-jagermonkey
Ian
2
@Ian V8 ist Open Source (BSD-Lizenz), Sie müssen also kein Reverse Engineering durchführen. Schauen Sie sich nur an, was sie tun.
dbkk
78

Es gibt viel mehr Impulse, um JavaScript-Interpreter hoch zu optimieren, weshalb zwischen Mozilla, Google und Microsoft so viele Ressourcen in sie gesteckt werden. JavaScript muss heruntergeladen, analysiert, kompiliert und in Echtzeit ausgeführt werden, während ein (normalerweise ungeduldiger) Mensch darauf wartet. Es muss ausgeführt werden, während eine Person mit ihm interagiert, und dies auf einem unkontrollierten Client-Ende Umgebung, die ein Computer, ein Telefon oder ein Toaster sein kann. Es muss effizient sein, um unter diesen Bedingungen effektiv laufen zu können.

Python und Ruby werden in einer Umgebung ausgeführt, die vom Entwickler / Bereitsteller gesteuert wird. Ein leistungsfähiger Server oder ein Desktop-System im Allgemeinen, bei dem der begrenzende Faktor beispielsweise Speicher- oder Festplatten-E / A und nicht die Ausführungszeit sind. Oder wo nicht-motorische Optimierungen wie Caching verwendet werden können. Für diese Sprachen ist es wahrscheinlich sinnvoller, sich auf die Sprach- und Bibliotheksfunktionen zu konzentrieren, die über die Geschwindigkeitsoptimierung eingestellt sind.

Der Nebeneffekt davon ist, dass wir zwei großartige Open-Source-JavaScript-Engines mit hoher Leistung haben, die für alle Arten von Anwendungen wie Node.js neu bestimmt werden können und werden.


quelle
43

Ein großer Teil davon hat mit Gemeinschaft zu tun. Python und Ruby haben größtenteils keine Unternehmensunterstützung. Niemand wird dafür bezahlt, Vollzeit an Python und Ruby zu arbeiten (und er wird insbesondere nicht dafür bezahlt, die ganze Zeit an CPython oder MRI zu arbeiten). V8 hingegen wird von dem leistungsstärksten IT-Unternehmen der Welt unterstützt.

Darüber hinaus kann V8 schneller sein, da das einzige, was für die V8-Leute wichtig ist, der Dolmetscher ist - sie haben keine Standardbibliothek, an der sie arbeiten können, keine Bedenken hinsichtlich des Sprachdesigns. Sie schreiben nur den Dolmetscher. Das ist es.

Es hat nichts mit dem Recht des geistigen Eigentums zu tun. Python wird auch nicht von Google-Leuten mitentwickelt (sein Schöpfer arbeitet dort zusammen mit einigen anderen Committern, aber sie werden nicht dafür bezahlt, an Python zu arbeiten).

Ein weiteres Hindernis für die Geschwindigkeit von Python ist Python 3. Die Übernahme scheint das Hauptanliegen der Sprachentwickler zu sein - bis zu dem Punkt, dass sie die Entwicklung neuer Sprachfunktionen eingefroren haben, bis andere Implementierungen aufholen.

Was die technischen Details betrifft, weiß ich nicht viel über Ruby, aber Python hat eine Reihe von Stellen, an denen Optimierungen verwendet werden könnten (und Unladen Swallow, ein Google-Projekt, hat damit begonnen, diese zu implementieren, bevor der Staub gebissen wurde). Hier sind einige der geplanten Optimierungen . Ich könnte sehen, dass Python in Zukunft an V8-Geschwindigkeit gewinnt, wenn eine JIT a la PyPy für CPython implementiert wird, aber das scheint für die kommenden Jahre nicht wahrscheinlich zu sein (der Schwerpunkt liegt derzeit auf der Einführung von Python 3, nicht auf einer JIT).

Viele sind auch der Meinung, dass Ruby und Python immens davon profitieren könnten, ihre jeweiligen globalen Interpreter-Sperren zu entfernen .

Sie müssen auch verstehen, dass Python und Ruby beide viel schwerere Sprachen als JS sind - sie bieten weitaus mehr Standardbibliothek, Sprachfunktionen und Struktur. Das Klassensystem der Objektorientierung allein fügt viel Gewicht hinzu (auf eine gute Weise, denke ich). Ich stelle mir Javascript fast als eine Sprache vor, die wie Lua eingebettet werden soll (und in vielerlei Hinsicht sind sie ähnlich). Ruby und Python verfügen über eine viel umfangreichere Palette von Funktionen, und diese Ausdruckskraft geht normalerweise zu Lasten der Geschwindigkeit.

Rafe Kettler
quelle
3
Tatsächlich wurde das Moratorium für neue Funktionen seit der jüngsten Veröffentlichung von Python 3.2 aufgehoben.
jd.
2
+1, aber würde ein Einfrieren neuer Sprachfunktionen nicht mehr Zeit für die Optimierung bedeuten?
Andrew Grimm
1
@ Andrew wenn nur. Der Schwerpunkt liegt darauf, Jython, IronPython und PyPy auf den neuesten Stand zu bringen, darauf zu warten, dass Bibliotheken zu Python 3 konvertiert werden, und Python 3 zu evangelisieren.
Rafe Kettler
2
"Das Klassensystem der Objektorientierung allein bringt viel Gewicht" - Moderne JavaScript-VMs wie V8 haben Klassen, sie sind nur implizit. Genau wie in Python müssen Sie keine Variable explizit in JavaScript eingeben, Sie müssen keine Klasse explizit eingeben. Die VM ist clever genug, um Ihren Code durchzugehen und Klassen zu extrahieren.
Benjamin Gruenbaum
1
So wie ich es verstehe, ist V8 eher ein JIT-Compiler als ein Interpreter ... Ich bin mir ziemlich sicher, dass es einen Unterschied zwischen den beiden gibt. Vielleicht nicht ... ich weiß es nicht.
Luke
24

Die Leistung scheint kein Hauptaugenmerk der Python-Kernentwickler zu sein, die der Meinung sind, dass "schnell genug" gut genug ist und dass Funktionen, die Programmierern helfen, produktiver zu sein, wichtiger sind als Funktionen, mit denen Computer Code schneller ausführen können.

In der Tat gab es jedoch ein (inzwischen aufgegebenes) Google-Projekt, unbeladen-schlucken , um einen schnelleren Python-Interpreter zu erstellen, der mit dem Standardinterpreter kompatibel ist. PyPy ist ein weiteres Projekt, mit dem ein schnelleres Python erstellt werden soll. Es gibt auch Psyco , den Vorläufer von PyPy, der viele Python-Skripte leistungssteigern kann, ohne den gesamten Interpreter auszutauschen , und Cython , mit dem Sie leistungsstarke C-Bibliotheken für Python mit einer ähnlichen Python-Syntax schreiben können.

irgendwie
quelle
13

Irreführende Frage. V8 ist eine JIT-Implementierung (ein Just-in-Time-Compiler) von JavaScript und in der beliebtesten Nicht-Browser-Implementierung Node.js um eine Ereignisschleife herum aufgebaut. CPython ist keine JIT und nicht ereignisreich. Diese sind jedoch in Python am häufigsten im PyPy-Projekt vorhanden - eine CPython 2.7-kompatible (und bald 3.0+) kompatible JIT. Und es gibt viele ereignisreiche Serverbibliotheken wie zum Beispiel Tornado. Es gibt reale Tests zwischen PyPy, auf dem Tornado ausgeführt wird, und Node.js, und die Leistungsunterschiede sind gering.

Handweberei
quelle
3
+1 für die Erwähnung von Tornado . Während es mit vergleichbarer Geschwindigkeit wie Node.js läuft, kann sein gen.engineModul zusammen mit Python-Generatoren und der yieldAnweisung ( seit 2.5 !!! Ihre asynchrone Codierung neu definieren.
Lukas Bünger
1
Seit Ihrem Beitrag hat pypy eine stabile 3.x-unterstützte Version veröffentlicht (und natürlich den Support weiter verbessert): morepypy.blogspot.fr/2014/06/pypy3-231-fulcrum.html
Zeograd
9

Ich bin gerade auf diese Frage gestoßen und es gibt auch einen großen technischen Grund für den Leistungsunterschied, der nicht erwähnt wurde. Python verfügt über ein sehr großes Ökosystem leistungsstarker Software-Erweiterungen. Die meisten dieser Erweiterungen sind jedoch aus Leistungsgründen in C oder anderen Low-Level-Sprachen geschrieben und stark an die CPython-API gebunden.

Es gibt viele bekannte Techniken (JIT, moderner Garbage Collector usw.), die verwendet werden könnten, um die CPython-Implementierung zu beschleunigen, aber alle würden wesentliche Änderungen an der API erfordern, wodurch die meisten Erweiterungen im Prozess beschädigt würden. CPython wäre schneller, aber vieles, was Python so attraktiv macht (der umfangreiche Software-Stack), würde verloren gehen. In diesem Fall gibt es mehrere schnellere Python-Implementierungen, die jedoch im Vergleich zu CPython nur eine geringe Traktion aufweisen.

Jason McCampbell
quelle
9

Aufgrund unterschiedlicher Designprioritäten und Anwendungsfallziele glaube ich.

Im Allgemeinen besteht der Hauptzweck von Skriptsprachen (auch als dynamische Sprachen bezeichnet) darin, ein "Klebstoff" zwischen Aufrufen nativer Funktionen zu sein. Und diese nativen Funktionen müssen a) die kritischsten / am häufigsten genutzten Bereiche abdecken und b) so effektiv wie möglich sein.

Hier ein Beispiel: jQuery-Sortierung führt zum Einfrieren von iOS Safari Das Einfrieren dort wird durch die übermäßige Verwendung von Get-by-Selector-Aufrufen verursacht. Wenn Get-by-Selector in nativem Code implementiert wäre und effektiv wäre, wäre dies überhaupt kein solches Problem.

Betrachten Sie die Ray-Tracer-Demo, die häufig für die V8-Demonstration verwendet wird. In der Python-Welt kann es in nativem Code implementiert werden, da Python alle Funktionen für native Erweiterungen bietet. Im V8-Bereich (clientseitige Sandbox) haben Sie jedoch keine anderen Optionen, als VM so [sub] effektiv wie möglich zu gestalten. Die einzige Möglichkeit, die Ray-Tracer-Implementierung dort zu sehen, ist die Verwendung von Skriptcode.

Also unterschiedliche Prioritäten und Motivationen.

In Sciter habe ich einen Test durchgeführt, indem ich den vollständigen jQurey-Kern nativ implementiert habe. Bei praktischen Aufgaben wie ScIDE (IDE aus HTML / CSS / Script) funktioniert eine solche Lösung meiner Meinung nach wesentlich besser als alle VM-Optimierungen.

c-smile
quelle
5

Wie andere bereits erwähnt haben, verfügt Python über einen performanten JIT-Compiler in Form von PyPy .

Sinnvolle Benchmarks zu erstellen ist immer subtil, aber ich habe zufällig einen einfachen Benchmark für K-Mittel , der in verschiedenen Sprachen geschrieben ist - Sie finden ihn hier . Eine der Einschränkungen bestand darin, dass die verschiedenen Sprachen alle denselben Algorithmus implementieren und sich bemühen sollten, einfach und idiomatisch zu sein (im Gegensatz zu einer für die Geschwindigkeit optimierten). Ich habe alle Implementierungen geschrieben, daher weiß ich, dass ich nicht betrogen habe, obwohl ich nicht für alle Sprachen behaupten kann, dass das, was ich geschrieben habe, idiomatisch ist (ich habe nur vorübergehende Kenntnisse über einige davon).

Ich behaupte keine endgültige Schlussfolgerung, aber PyPy gehörte zu den schnellsten Implementierungen, die ich erhalten habe, weitaus besser als Node. CPython war stattdessen am langsamsten Ende der Rangliste.

Andrea
quelle
5

Die Aussage ist nicht genau richtig

Genau wie V8 nur eine Implementierung für JS ist, ist CPython nur eine Implementierung für Python. Pypy hat Leistungen, die zu V8 passen .

Außerdem gibt es das Problem der wahrgenommenen Leistung: Da V8 von Haus aus nicht blockiert, führt Web Dev zu leistungsfähigeren Projekten, da Sie die E / A-Wartezeit speichern. Und V8 wird hauptsächlich für Dev Web verwendet, wo E / A der Schlüssel ist, also vergleichen sie es mit ähnlichen Projekten. Sie können Python jedoch in vielen, vielen anderen Bereichen als dem Webentwickler verwenden. Sie können sogar C-Erweiterungen für viele Aufgaben verwenden, z. B. für wissenschaftliche Berechnungen oder Verschlüsselung, und Daten mit hervorragenden Leistungen verarbeiten.

Im Web blockieren die beliebtesten Python- und Ruby-Projekte. Insbesondere Python hat das Erbe des synchronen WSGI-Standards, und Frameworks wie das berühmte Django basieren darauf.

Sie können asynchrones Python (wie bei Twisted, Tornado, gevent oder asyncio) oder Ruby schreiben. Aber es wird nicht oft gemacht. Die besten Tools blockieren immer noch.

Dies sind jedoch einige Gründe, warum die Standardimplementierungen in Ruby und Python nicht so schnell sind wie in V8.

Erfahrung

Wie Jörg W. Mittag betonte, sind die Leute, die an V8 arbeiten, VM-Genies. Python ist eine Gruppe leidenschaftlicher Leute, die in vielen Bereichen sehr gut sind, aber nicht so auf VM-Tuning spezialisiert sind.

Ressourcen

Die Python Software Foundation hat sehr wenig Geld: weniger als 40.000 pro Jahr, um in Python zu investieren. Das ist ein bisschen verrückt, wenn man denkt, dass große Player wie Google, Facebook oder Apple Python verwenden, aber es ist die hässliche Wahrheit: Die meiste Arbeit wird kostenlos erledigt. Die Sprache, die Youtube antreibt und vor Java existierte, wurde von Freiwilligen handgefertigt.

Sie sind kluge und engagierte Freiwillige, aber wenn sie feststellen, dass sie mehr Saft auf einem Feld benötigen, können sie nicht um 300.000 bitten, um einen erstklassigen Spezialisten für dieses Fachgebiet einzustellen. Sie müssen sich nach jemandem umsehen, der das kostenlos macht.

Während dies funktioniert, bedeutet dies, dass Sie sehr vorsichtig mit Ihren Prioritäten sein müssen. Daher müssen wir uns jetzt Folgendes ansehen:

Ziele

Selbst mit den neuesten modernen Funktionen ist das Schreiben von Javascript schrecklich. Sie haben Probleme mit dem Umfang, sehr wenige Sammlungen, schreckliche Manipulationen an Zeichenfolgen und Arrays, fast keine Standardliste außer Datum, Mathematik und regulären Ausdrücken und keinen syntaktischen Zucker, selbst für sehr häufige Operationen.

Aber in V8 hast du Geschwindigkeit.

Dies liegt daran, dass Geschwindigkeit das Hauptziel von Google war, da dies ein Engpass beim Rendern von Seiten in Chrome ist.

In Python ist die Benutzerfreundlichkeit das Hauptziel. Weil es fast nie der Engpass im Projekt ist. Die knappe Ressource hier ist die Entwicklerzeit. Es ist für den Entwickler optimiert.

e-satis
quelle
1

Weil JavaScript-Implementierungen sich nicht um die Abwärtskompatibilität ihrer Bindungen kümmern müssen.

Bis vor kurzem waren die einzigen Benutzer der JavaScript-Implementierungen Webbrowser. Aus Sicherheitsgründen hatten nur die Webbrowser-Anbieter das Recht, die Funktionalität durch Schreiben von Bindungen an die Laufzeiten zu erweitern. Daher war es nicht erforderlich, die C-API der Bindungen abwärtskompatibel zu halten. Es war zulässig, die Webbrowser-Entwickler aufzufordern, ihren Quellcode zu aktualisieren, während sich die JavaScript-Laufzeiten weiterentwickelten. sie arbeiteten sowieso zusammen. Sogar V8, das ein Neuling im Spiel war und auch von einem sehr sehr erfahrenen Entwickler geleitet wurde, hat die API geändert, als sie besser wurde.

OTOH Ruby wird (hauptsächlich) serverseitig verwendet. Viele beliebte Ruby-Erweiterungen werden als C-Bindungen geschrieben (betrachten Sie einen RDBMS-Treiber). Mit anderen Worten, Ruby wäre ohne die Aufrechterhaltung der Kompatibilität niemals erfolgreich gewesen.

Der Unterschied besteht heute noch teilweise. Entwickler, die node.js verwenden, beschweren sich, dass es schwierig ist, ihre nativen Erweiterungen abwärtskompatibel zu halten, da V8 die API im Laufe der Zeit ändert (und dies ist einer der Gründe, warum node.js gegabelt wurde). IIRC Ruby verfolgt in dieser Hinsicht immer noch einen viel konservativeren Ansatz.

Kazuho
quelle
1

V8 ist dank JIT, Kurbelwelle, Typ-Inferencer und datenoptimiertem Code schnell. Markierte Zeiger, NaN-Markierung von Doppel. Und natürlich werden in der Mitte normale Compiler-Optimierungen durchgeführt.

Die einfachen Ruby-, Python- und Perl-Engines führen keine dieser Funktionen aus, sondern nur geringfügige grundlegende Optimierungen.

Das einzige große VM, das nahe kommt, ist Luajit, das nicht einmal Typinferenz, konstante Faltung, NaN-Tagging oder Ganzzahlen ausführt, sondern ähnliche kleine Code- und Datenstrukturen verwendet, die nicht so fett sind wie die schlechten Sprachen. Und meine dynamischen Prototypsprachen Potion und P2 haben ähnliche Funktionen wie Luajit und übertreffen Version 8. Mit einem optionalen Typsystem, dem "schrittweisen Tippen", können Sie v8 leicht übertreffen, da Sie die Kurbelwelle umgehen können. Siehe Dart.

Die bekannten optimierten Backends wie Pypy oder Jruby leiden immer noch unter verschiedenen Überentwicklungstechniken.

rurban
quelle
Siehe auch github.com/rahul080327/medusa
Günter Zöchbauer