Qu'est-ce qui bloque Ruby, Python pour obtenir la vitesse Javascript V8? [fermé]


261

Existe-t-il des fonctionnalités Ruby / Python qui bloquent la mise en œuvre des optimisations (par exemple la mise en cache en ligne ) du moteur V8?

Python est co-développé par Google, donc il ne devrait pas être bloqué par des brevets logiciels.

Ou c'est plutôt une question de ressources mises dans le projet V8 par Google.


6
L'introspection et la surcharge des opérateurs sont probablement des problèmes importants, mais je ne connais pas assez bien JS pour vous donner une vraie réponse. Le projet PyPy est probablement la meilleure chance pour Python d'atteindre des vitesses JS.
ncoghlan

11
Avez-vous des exemples où PyPy est plus lent que V8, sauf pour la fusillade en langage informatique qui est des conneries complètes (regardez simplement comment les choses sont implémentées différemment dans différentes langues là-bas). Ou est-ce simplement le champ de distorsion de la réalité de Google?
fijal

3
La V8 n'est pas tout à fait à la hauteur de Python. Attendez que V8 doive implémenter la spécification Javascript 1.8 pour faire une meilleure comparaison. Et à ce stade, je suis sûr que quelqu'un tentera d'implémenter PyPy sur le moteur V8 à la place de Javascript.
Michael Dillon

14
Pourquoi êtes-vous si sûr que V8 est plus rapide que Python ou Ruby? À quoi?
jcoffland

6
V8 est absolument plus rapide que Python / Ruby. Faites n'importe quel type de benchmark que vous voulez, du simple micro-benchmark à une application complète du monde réel écrite idiomatiquement dans les deux environnements. C'est un ordre de grandeur plus rapide pour la plupart des opérations en langage natif (c'est-à-dire des choses qui ne sont pas déléguées au code C en Python).
Hejazzman

Réponses:


519

Qu'est-ce qui bloque Ruby, Python pour obtenir la vitesse Javascript V8?

Rien.

Bon, d'accord: de l'argent. (Et le temps, les gens, les ressources, mais si vous avez de l'argent, vous pouvez les acheter.)

V8 a une équipe d'ingénieurs brillants, hautement spécialisés, hautement expérimentés (et donc très bien payés) qui y travaillent, qui ont des décennies d'expérience (je parle individuellement - collectivement, cela ressemble plus à des siècles) dans la création d'une exécution haute performance moteurs pour les langages OO dynamiques. Ce sont essentiellement les mêmes personnes qui ont également créé la JVM Sun HotSpot (parmi beaucoup d'autres).

Lars Bak, le développeur principal, travaille littéralement sur les machines virtuelles depuis 25 ans (et toutes ces machines virtuelles ont conduit à la V8), ce qui est essentiellement toute sa vie (professionnelle). Certaines personnes écrivant des machines virtuelles Ruby n'ont même pas 25 ans.

Existe-t-il des fonctionnalités Ruby / Python qui bloquent la mise en œuvre des optimisations (par exemple la mise en cache en ligne) du moteur V8?

Étant donné qu'au moins IronRuby, JRuby, MagLev, MacRuby et Rubinius ont une mise en cache en ligne monomorphe (IronRuby) ou polymorphe, la réponse est évidemment non.

Les implémentations Ruby modernes font déjà beaucoup d'optimisations. Par exemple, pour certaines opérations, la Hashclasse de Rubinius est plus rapide que celle de YARV. Maintenant, cela ne semble pas vraiment excitant jusqu'à ce que vous réalisiez que la Hashclasse de Rubinius est implémentée en 100% Ruby pur, tandis que YARV est implémentée en 100% optimisé à la main C.

Ainsi, au moins dans certains cas, Rubinius peut générer un meilleur code que GCC!

Ou c'est plutôt une question de ressources mises dans le projet V8 par Google.

Oui. Pas seulement Google. La lignée du code source de V8 a maintenant 25 ans. Les personnes qui travaillent sur V8 ont également créé le Self VM (à ce jour l'un des moteurs d'exécution de langage OO dynamique les plus rapides jamais créés), le Animorphic Smalltalk VM (à ce jour l'un des moteurs d'exécution Smalltalk les plus rapides jamais créés), le HotSpot JVM (la JVM la plus rapide jamais créée, probablement la période de VM la plus rapide) et OOVM (l'une des VM Smalltalk les plus efficaces jamais créées).

En fait, Lars Bak, le développeur principal de V8, a travaillé sur chacun d'entre eux, ainsi que sur quelques autres.


1
Pouvons-nous avoir de la documentation de référence sur "Étant donné qu'au moins IronRuby, JRuby, MagLev, MacRuby et Rubinius ont une mise en cache en ligne monomorphe (IronRuby) ou polymorphe, la réponse est évidemment non." S'il vous plaît?
WDRust

14
SpiderMonkey a des performances comparables, alors comment Mozilla l'a-t-il fait à l'époque? Ils ont de l'argent très limité ..
Salman von Abbas

8
@SalmanPK: ce n'est pas leur première machine virtuelle, et il y a aussi des gens intelligents qui travaillent chez Mozilla.
Matthieu M.

3
@SalmanPK, miguel: Mozilla a créé sa machine virtuelle JS au moins en partie par reverse engineering V8. blog.mozilla.org/dmandelin/2010/09/08/presenting-jagermonkey
Ian

2
@Ian V8 est open source (licence BSD), donc pas besoin de faire de l'ingénierie inverse, regardez simplement ce qu'ils font.
dbkk

78

Il y a beaucoup plus d'impulsion pour optimiser fortement les interpréteurs JavaScript, c'est pourquoi nous voyons tant de ressources y être mises entre Mozilla, Google et Microsoft. JavaScript doit être téléchargé, analysé, compilé et exécuté en temps réel pendant qu'un être humain (généralement impatient) l'attend, il doit s'exécuter pendant qu'une personne interagit avec lui, et cela se fait dans un client non contrôlé. environnement qui pourrait être un ordinateur, un téléphone ou un grille-pain. Il doit être efficace pour fonctionner efficacement dans ces conditions.

Python et Ruby sont exécutés dans un environnement contrôlé par le développeur / déployeur. Un serveur costaud ou un système de bureau généralement où le facteur limitant sera des choses comme la mémoire ou les E / S disque et non le temps d'exécution. Ou lorsque des optimisations non liées au moteur comme la mise en cache peuvent être utilisées. Pour ces langues, il est probablement plus judicieux de se concentrer sur les fonctionnalités de langue et de bibliothèque sur l'optimisation de la vitesse.

L'avantage secondaire de cela est que nous avons deux excellents moteurs JavaScript open source hautes performances qui peuvent et sont réutilisés pour toutes sortes d'applications telles que Node.js.


43

Une bonne partie de cela a à voir avec la communauté. Python et Ruby n'ont pour la plupart aucun support d'entreprise. Personne n'est payé pour travailler à temps plein sur Python et Ruby (et ils ne sont surtout pas payés pour travailler sur CPython ou MRI tout le temps). La V8, en revanche, est soutenue par la société informatique la plus puissante du monde.

De plus, V8 peut être plus rapide car la seule chose qui compte pour les gens de V8 est l'interprète - ils n'ont pas de bibliothèque standard sur laquelle travailler, pas de soucis concernant la conception du langage. Ils écrivent juste l'interprète. C'est tout.

Cela n'a rien à voir avec le droit de la propriété intellectuelle. Python n'est pas non plus co-développé par les gars de Google (son créateur y travaille avec quelques autres committers, mais ils ne sont pas payés pour travailler sur Python).

Un autre obstacle à la vitesse de Python est Python 3. Son adoption semble être la principale préoccupation des développeurs de langage - au point qu'ils ont gelé le développement de nouvelles fonctionnalités de langage jusqu'à ce que d'autres implémentations rattrapent leur retard.

En ce qui concerne les détails techniques, je ne connais pas grand-chose à Ruby, mais Python a un certain nombre d'endroits où les optimisations pourraient être utilisées (et Unladen Swallow, un projet Google, a commencé à les mettre en œuvre avant de mordre la poussière). Voici quelques-unes des optimisations prévues . Je pourrais voir Python gagner en vitesse V8 à l'avenir si un JIT à la PyPy est implémenté pour CPython, mais cela ne semble pas probable pour les années à venir (l'accent est actuellement sur l'adoption de Python 3, pas un JIT).

Beaucoup pensent également que Ruby et Python pourraient bénéficier énormément de la suppression de leurs verrous d'interpréteur global respectifs .

Vous devez également comprendre que Python et Ruby sont tous deux des langages beaucoup plus lourds que JS - ils fournissent beaucoup plus en termes de bibliothèque standard, de fonctionnalités de langage et de structure. Le système de classe d'orientation des objets à lui seul ajoute beaucoup de poids (dans le bon sens, je pense). Je pense presque à Javascript comme un langage conçu pour être intégré, comme Lua (et à bien des égards, ils sont similaires). Ruby et Python ont un ensemble de fonctionnalités beaucoup plus riche, et cette expressivité va généralement se faire au détriment de la vitesse.


3
En fait, le moratoire sur les nouvelles fonctionnalités a été levé depuis la récente version de Python 3.2.
jd.

2
+1, mais un gel des nouvelles fonctionnalités linguistiques ne signifierait-il pas plus de temps à consacrer à l'optimisation?
Andrew Grimm

1
@Andrew si seulement. L'accent est mis sur la mise à niveau de Jython, IronPython et PyPy, l'attente de la conversion des bibliothèques en Python 3 et l'évangélisation de Python 3.
Rafe Kettler

2
«Le système de classe d'orientation d'objet à lui seul ajoute beaucoup de poids» - Les machines virtuelles JavaScript modernes comme V8 ont des classes, elles sont simplement implicites. Tout comme en Python, vous n'avez pas à taper explicitement une variable en JavaScript, vous n'avez pas à taper explicitement une classe. La machine virtuelle est suffisamment intelligente pour parcourir votre code et extraire des classes.
Benjamin Gruenbaum

1
Si je comprends bien, V8 est un compilateur JIT plutôt qu'un interprète ... Je suis sûr qu'il y a une distinction entre les deux. Peut-être pas ... je ne sais pas.
Luke

24

Les performances ne semblent pas être un objectif majeur des développeurs Python principaux, qui semblent estimer que "assez vite" est assez bon, et que les fonctionnalités qui aident les programmeurs à être plus productifs sont plus importantes que les fonctionnalités qui aident les ordinateurs à exécuter le code plus rapidement.

En effet, cependant, il y avait un projet (désormais abandonné) de Google, à vide-hirondelle , pour produire un interpréteur Python plus rapide compatible avec l'interpréteur standard. PyPy est un autre projet qui vise à produire un Python plus rapide. Il existe également Psyco , le précurseur de PyPy, qui peut améliorer les performances de nombreux scripts Python sans changer l'intégralité de l'interpréteur, et Cython , qui vous permet d'écrire des bibliothèques C hautes performances pour Python en utilisant quelque chose de très similaire à la syntaxe Python.


13

Question trompeuse. V8 est une implémentation JIT (un compilateur juste à temps) de JavaScript et dans son implémentation non navigateur la plus populaire Node.js, elle est construite autour d'une boucle d'événement. CPython n'est pas un JIT et n'est pas événementiel. Mais ceux-ci existent en Python le plus souvent dans le projet PyPy - un JIT compatible CPython 2.7 (et bientôt 3.0+). Et il y a des tas de bibliothèques de serveurs événementiels comme Tornado par exemple. Des tests dans le monde réel existent entre PyPy exécutant Tornado vs Node.js et les différences de performances sont légères.


3
+1 pour avoir mentionné Tornado . Alors qu'il va à une vitesse comparable à Node.js, son gen.enginemodule avec les générateurs Python et l' yieldinstruction ( depuis 2.5 !!! peut redéfinir votre codage asynchrone.
Lukas Bünger

1
Depuis votre article, pypy a publié une version stable 3.x prise en charge (et continue d'améliorer le support, bien sûr): morepypy.blogspot.fr/2014/06/pypy3-231-fulcrum.html
Zeograd

9

Je viens de tomber sur cette question et il y a aussi une grande raison technique pour la différence de performance qui n'a pas été mentionnée. Python possède un très vaste écosystème d'extensions logicielles puissantes, mais la plupart de ces extensions sont écrites en C ou dans d'autres langages de bas niveau pour les performances et sont fortement liées à l'API CPython.

Il existe de nombreuses techniques bien connues (JIT, garbage collector moderne, etc.) qui pourraient être utilisées pour accélérer la mise en œuvre de CPython, mais toutes nécessiteraient des modifications substantielles de l'API, cassant la plupart des extensions du processus. CPython serait plus rapide, mais une grande partie de ce qui rend Python si attrayant (la pile logicielle étendue) serait perdue. Par exemple, il existe plusieurs implémentations Python plus rapides, mais elles ont peu de traction par rapport à CPython.


9

En raison des différentes priorités de conception et des objectifs des cas d'utilisation, je crois.

En général, le but principal des langages de script (aka dynamiques) est d'être une "colle" entre les appels de fonctions natives. Et ces fonctions natives doivent a) couvrir les zones les plus critiques / fréquemment utilisées et b) être aussi efficaces que possible.

Voici un exemple: tri jQuery provoquant le gel d'iOS Safari Le gel est provoqué par une utilisation excessive des appels get-by-selector. Si get-by-selector devait être implémenté dans du code natif et efficacement, ce ne serait pas du tout un problème.

Considérez la démo de ray-tracer qui est fréquemment utilisée pour la démonstration de V8. Dans le monde Python, il peut être implémenté en code natif car Python fournit toutes les fonctionnalités pour les extensions natives. Mais dans le domaine V8 (sandbox côté client), vous n'avez pas d'autres options que de rendre la VM [sous] aussi efficace que possible. Et donc la seule option de voir l'implémentation de ray-tracer est d'utiliser un code de script.

Donc différentes priorités et motivations.

Dans Sciter, j'ai fait un test en implémentant nativement le noyau jQurey. Sur des tâches pratiques comme ScIDE (IDE en HTML / CSS / Script), je pense qu'une telle solution fonctionne beaucoup mieux que toutes les optimisations de VM.


5

Comme d'autres personnes l'ont mentionné, Python possède un compilateur JIT performant sous la forme de PyPy .

Faire des repères significatifs est toujours subtil, mais il se trouve que j'ai un simple repère de K-means écrit dans différentes langues - vous pouvez le trouver ici . L'une des contraintes était que les différents langages devaient tous implémenter le même algorithme et s'efforcer d'être simples et idiomatiques (par opposition à optimisés pour la vitesse). J'ai écrit toutes les implémentations, donc je sais que je n'ai pas triché, bien que je ne puisse pas prétendre pour toutes les langues que ce que j'ai écrit est idiomatique (je n'ai qu'une connaissance passagère de certaines d'entre elles).

Je ne revendique aucune conclusion définitive, mais PyPy était parmi les implémentations les plus rapides que j'ai eues, bien mieux que Node. CPython, au contraire, était à l'extrémité la plus lente du classement.


5

L'énoncé n'est pas exactement vrai

Tout comme V8 n'est qu'une implémentation pour JS, CPython n'est qu'une implémentation pour Python. Pypy a des performances correspondant aux V8 .

Il y a aussi le problème des performances perçues: puisque la V8 est nativement non bloquante, le développement Web conduit à des projets plus performants car vous enregistrez l'attente d'E / S. Et V8 est principalement utilisé pour le Web de développement où les E / S sont essentielles, ils le comparent donc à des projets similaires. Mais vous pouvez utiliser Python dans de nombreux autres domaines que le développement Web. Et vous pouvez même utiliser des extensions C pour de nombreuses tâches, telles que les calculs scientifiques ou le chiffrement, et crunch des données avec des perfs flamboyants.

Mais sur le Web, les projets Python et Ruby les plus populaires bloquent. Python, en particulier, a l'héritage du standard WSGI synchrone, et des frameworks comme le célèbre Django sont basés sur lui.

Vous pouvez écrire en Python asynchrone (comme avec Twisted, Tornado, gevent ou asyncio) ou Ruby. Mais ce n'est pas fait souvent. Les meilleurs outils bloquent toujours.

Cependant, ce sont quelques raisons pour lesquelles les implémentations par défaut dans Ruby et Python ne sont pas aussi rapides que V8.

Expérience

Comme l'a souligné Jörg W Mittag, les gars qui travaillent sur V8 sont des génies de la VM. Python est un groupe de passionnés, très bon dans de nombreux domaines, mais il n'est pas aussi spécialisé dans le réglage de VM.

Ressources

La fondation Python Software a très peu d'argent: moins de 40k en un an pour investir dans Python. C'est un peu fou quand on pense que de gros joueurs comme Google, Facebook ou Apple utilisent tous Python, mais c'est la vilaine vérité: la plupart du travail est fait gratuitement. Le langage qui anime Youtube et qui existait avant Java a été fabriqué à la main par des bénévoles.

Ce sont des bénévoles intelligents et dévoués, mais lorsqu'ils identifient qu'ils ont besoin de plus de jus dans un domaine, ils ne peuvent pas demander 300k pour embaucher un spécialiste de premier ordre dans ce domaine d'expertise. Ils doivent chercher quelqu'un qui le ferait gratuitement.

Bien que cela fonctionne, cela signifie que vous devez faire très attention à vos priorités. Par conséquent, nous devons maintenant examiner:

Objectifs

Même avec les dernières fonctionnalités modernes, l'écriture de Javascript est terrible. Vous avez des problèmes de portée, très peu de collections, de terribles manipulations de chaînes et de tableaux, presque aucune liste std en dehors de la date, des mathématiques et des expressions régulières, et aucun sucre syntaxique même pour des opérations très courantes.

Mais en V8, vous avez de la vitesse.

En effet, la vitesse était l'objectif principal de Google, car il s'agit d'un goulot d'étranglement pour le rendu des pages dans Chrome.

En Python, l'utilisabilité est l'objectif principal. Parce que ce n'est presque jamais le goulot d'étranglement du projet. La ressource rare ici est le temps des développeurs. Il est optimisé pour le développeur.


1

Parce que les implémentations JavaScript n'ont pas à se soucier de la compatibilité descendante de leurs liaisons.

Jusqu'à récemment, les seuls utilisateurs des implémentations JavaScript étaient les navigateurs Web. En raison d'exigences de sécurité, seuls les fournisseurs de navigateurs Web avaient le privilège d'étendre la fonctionnalité en écrivant des liaisons aux runtimes. Ainsi, il n'était pas nécessaire de garder l'API C des liaisons rétrocompatibles, il était permis de demander aux développeurs de navigateurs Web de mettre à jour leur code source au fur et à mesure que les temps d'exécution JavaScript évoluaient; ils travaillaient de toute façon ensemble. Même V8, qui était un retardataire dans le jeu, et également dirigé par un développeur très très expérimenté, a changé l'API au fur et à mesure de son amélioration.

OTOH Ruby est utilisé (principalement) côté serveur. De nombreuses extensions ruby ​​populaires sont écrites sous forme de liaisons C (pensez à un pilote SGBDR). En d'autres termes, Ruby n'aurait jamais réussi sans maintenir la compatibilité.

Aujourd'hui, la différence existe encore dans une certaine mesure. Les développeurs utilisant node.js se plaignent qu'il est difficile de garder leurs extensions natives rétrocompatibles, car V8 change l'API au fil du temps (et c'est l'une des raisons pour lesquelles node.js a été bifurqué). Le rubis de l'IIRC adopte toujours une approche beaucoup plus conservatrice à cet égard.


1

Le V8 est rapide grâce au JIT, au vilebrequin, à l'inférenceur de type et au code optimisé pour les données. Pointeurs marqués, marquage NaN des doubles. Et bien sûr, il fait des optimisations normales du compilateur au milieu.

Les moteurs plain ruby, python et perl ne font ni l'un ni l'autre, juste des optimisations de base mineures.

Le seul vm majeur qui se rapproche est luajit, qui ne fait même pas d'inférence de type, de pliage constant, de marquage NaN ni d'entiers, mais utilise un petit code et des structures de données similaires, pas aussi gros que les mauvais langages. Et mon prototype de langages dynamiques, potion et p2 ont des fonctionnalités similaires à luajit et surpassent la v8. Avec un système de typage optionnel, "typage progressif", vous pourriez facilement surpasser la v8, car vous pouvez contourner le vilebrequin. Voir fléchette.

Les backends optimisés connus, comme pypy ou jruby, souffrent encore de diverses techniques de suringénierie.


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.