web-dev-qa-db-fra.com

Qu'est-ce qui empêche Ruby, Python d'obtenir la vitesse Javascript V8?

Existe-t-il des fonctionnalités de Ruby/Python qui bloquent la mise en oeuvre des optimisations (par exemple, mise en cache inline ) du moteur V8?

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

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

261
Greg Dan

Qu'est-ce qui empêche Ruby, Python d'obtenir la vitesse Javascript V8?

Rien.

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

V8 dispose d'une équipe d'ingénieurs brillants, hautement spécialisés, hautement expérimentés (et donc bien rémunérés), dotés de plusieurs décennies d'expérience (je parle de manière individuelle - collectivement, cela ressemble plus à des siècles) à la création d'une exécution hautes performances. moteurs pour OO langues 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 ont été jusqu'à la V8), ce qui est essentiellement sa vie (professionnelle). Certaines personnes qui écrivent Ruby Les machines virtuelles n'ont même pas 25 ans.

Existe-t-il des fonctionnalités de Ruby/Python qui bloquent la mise en œuvre des optimisations (par exemple, la mise en cache intégrée) que possède le moteur V8?

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

Les implémentations modernes de Ruby effectuent déjà de nombreuses optimisations. Par exemple, pour certaines opérations, la classe Hash de Rubinius est plus rapide que celle de YARV. Maintenant, cela ne semble pas très excitant jusqu'à ce que vous réalisiez que la classe Hash de Rubinius est implémentée en Ruby pur à 100%, tandis que celle de YARV est implémentée dans un C optimisé à la main à 100%.

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

Ou bien 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 25 ans maintenant. Les personnes qui travaillent sur la V8 ont également créé le Self VM (l'un des moteurs d'exécution du langage les plus dynamiques OO jamais créés), l'Animorphic Smalltalk VM. _ (à ce jour, l'un des moteurs d'exécution Smalltalk les plus rapides jamais créés), la JVM HotSpot (la machine JVM la plus rapide jamais créée, probablement la période la plus rapide VM) et l'OOVM (l'une des machines virtuelles Smalltalk les plus efficaces jamais créées ).

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

519
Jörg W Mittag

L'optimisation des interpréteurs JavaScript est de plus en plus dynamique. C'est pourquoi nous voyons tant de ressources 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 tant qu'une personne interagit avec, et cela se fait dans une fin client non contrôlée. 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 ou un système de bureau costaud où le facteur limitant sera généralement la mémoire ou les E/S du disque, et non le temps d'exécution. Ou encore, lorsque des optimisations non liées au moteur telles que la mise en cache peuvent être utilisées. Pour ces langages, il est probablement plus logique de se concentrer sur l’optimisation de la vitesse des langages et des bibliothèques.

L’avantage supplémentaire est que nous disposons de deux excellents moteurs JavaScript open source hautes performances qui peuvent être réutilisés pour toute sorte d’applications telles que Node.js.

78
user748221

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 sur Python et Ruby à temps plein (et surtout, il n'est pas payé pour travailler sur CPython ou sur une IRM en tout temps). La V8, en revanche, est supportée par la société informatique la plus puissante du monde.

En outre, la version 8 peut être plus rapide car l'interprète n'a d'importance que pour les utilisateurs de la version 8: ils n'ont pas de bibliothèque standard sur laquelle travailler, pas de problème de conception de langage. Ils écrivent simplement l'interprète. C'est ça.

Cela n'a rien à voir avec le droit de la propriété intellectuelle. Python n'est pas non plus co-développé par Google (son créateur y travaille avec quelques autres auteurs, 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 langages - au point qu'ils ont gelé le développement de nouvelles fonctionnalités de langage jusqu'à d'autres implémentations. rattraper.

Pour ce qui est des détails techniques, je ne connais pas grand chose à Ruby, mais Python a plusieurs endroits où des optimisations pourraient être utilisées (et Unladen Swallow, un projet de Google, a commencé à les implémenter avant de mordre la poussière. ) Voici certaines des optimisations qu'ils ont planifiées . Je pouvais voir que Python gagnait en vitesse V8 à l'avenir si un JIT à la PyPy était implémenté pour CPython, mais cela ne semble pas probable pour les années à venir (l'accent est maintenant mis sur Python 3 adoption, pas une EMI).

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

Vous devez également comprendre que Python et Ruby sont des langages beaucoup plus lourds que JS - ils fournissent beaucoup plus de possibilités en termes de bibliothèque standard, de fonctionnalités de langage et de structure. Le système de classes orienté objet à 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 bien plus riche, et cette expressivité se fait généralement au détriment de la vitesse.

43
Rafe Kettler

Les performances ne semblent pas être l’une des préoccupations principales des développeurs Python, qui semblent penser que la rapidité est suffisante et que les fonctionnalités permettant aux programmeurs d’être plus productifs sont plus importantes que celles qui aider les ordinateurs à exécuter le code plus rapidement.

En réalité, cependant, il existait un projet Google (maintenant abandonné), nladen-swallow , pour produire un interpréteur plus rapide Python 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 booster les performances de nombreux scripts Python sans modifier l'intégralité de l'interprète, et Cython , qui vous permet d'écrire des bibliothèques C hautes performances pour Python en utilisant quelque chose qui ressemble beaucoup à la syntaxe Python.

24
kindall

Question trompeuse. V8 est une implémentation JavaScript de JIT (compilateur "juste à temps") et, dans sa plus populaire implémentation sans navigateur, Node.js, elle est construite autour d'une boucle d'événement. CPython n'est pas un JIT et n'est pas eventé. Mais ils existent dans Python, le plus souvent dans le projet PyPy - un JIT compatible CPython 2.7 (et qui sera bientôt 3.0+). Et il existe une multitude de bibliothèques de serveurs à l'épreuve des événements, comme Tornado, par exemple. Des tests réels existent entre PyPy et Tornado vs Node.js et les différences de performances sont faibles.

13
Handloomweaver

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

En général, l’objectif principal du langage de script (dynamique.k.a.) est d’être un "liant" 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 de iOS Safari Le gel est dû à une utilisation excessive des appels de sélecteur. Si get-by-selector était implémenté dans le code natif, ce ne serait pas un problème du tout.

Envisagez une démo de ray-tracer qui est fréquemment utilisée pour la démonstration en V8. Dans Python world, il peut être implémenté en code natif car Python fournit toutes les fonctionnalités nécessaires aux extensions natives. Mais dans le domaine V8 (sandbox côté client), vous n'avez pas d'autre option que de rendre VM aussi efficace que possible. Et donc la seule option que nous voyons dans l'implémentation de ray-tracer consiste à utiliser du code script.

Donc, différentes priorités et motivations.

Dans Sciter J'ai effectué un test en implémentant de manière native un noyau jQurey presque complet. Pour des tâches pratiques telles que ScIDE (IDE en HTML/CSS/Script), j’estime que cette solution fonctionne bien mieux que n’importe quelle optimisation VM.

9
c-smile

Je viens de tomber sur cette question et il y a aussi une grande raison technique à la différence de performance qui n'a pas été mentionnée. Python possède un très grand é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 améliorer les performances et sont fortement liées à l'API CPython.

Il existe de nombreuses techniques 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, interrompant la plupart des extensions du processus. CPython serait plus rapide, mais beaucoup de ce qui rendait Python si attrayant (la pile logicielle étendue) serait perdu. À titre d’exemple, il existe plusieurs implémentations Python plus rapides, mais leur impact est faible par rapport à CPython.

9
Jason McCampbell

L'affirmation n'est pas tout à fait vraie

Tout comme la 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 de la performance perçue: puisque la V8 n’est en principe pas bloquante, Web dev conduit à des projets plus performants car vous enregistrez le IO attente. Et la V8 est principalement utilisée pour dev Web, où IO est la clé, ce qui permet de la comparer à des projets similaires. Mais vous pouvez utiliser Python dans de nombreux autres domaines que Web Dev. Et vous pouvez même utiliser des extensions C pour de nombreuses tâches, telles que des calculs scientifiques ou le cryptage, et traiter des données avec des perfs époustouflants.

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 celui-ci.

Vous pouvez écrire 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 certaines des raisons pour lesquelles les implémentations par défaut dans Ruby et Python ne sont pas aussi rapides que V8.

Expérience

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

Ressources

La Python Software Foundation dispose de très peu d’argent: moins de 40 000 euros dans un an pour investir dans Python. C’est un peu fou quand on pense que de grands joueurs comme Google, Facebook ou Apple utilisent tous Python, mais c’est la pire vérité: la plupart du travail est fait gratuitement. Le langage qui fait fonctionner Youtube et qui existait avant Java a été créé à la main par des volontaires.

Ce sont des volontaires intelligents et dévoués, mais lorsqu'ils identifient avoir besoin de plus de jus dans un domaine, ils ne peuvent pas demander 300 000 $ pour engager un spécialiste de premier plan 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 cadrage, très peu de collections, une manipulation de chaînes et de tableaux épouvantables, presque aucune liste stdlist en dehors de la date, des maths et des expressions rationnelles, 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'agissait d'un goulot d'étranglement pour le rendu des pages dans Chrome.

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

5
e-satis

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

Faire des repères significatifs est toujours subtile, mais 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 prétends pas avoir de conclusion définitive, mais PyPy a été l’une des implémentations les plus rapides que j’ai eu, bien meilleure que Node. CPython, au lieu de cela, était à la fin la plus lente du classement.

5
Andrea

Parce que les implémentations JavaScript n'ont pas besoin de se soucier de la compatibilité ascendante 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 ont le privilège d'étendre la fonctionnalité en écrivant des liaisons dans les environnements d'exécution. Il n'était donc pas nécessaire de conserver la compatibilité ascendante de l'API C des liaisons, il était permis de demander aux développeurs de navigateurs Web de mettre à jour leur code source au fur et à mesure de l'évolution du moteur d'exécution JavaScript; ils travaillaient de toute façon ensemble. Même la V8, arrivée tardive dans le jeu et également dirigée par un développeur très expérimenté, a modifié 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 en tant que liaisons C (considérons un pilote de 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 du fait qu'il est difficile de conserver la compatibilité ascendante de leurs extensions natives, car la version 8 modifie l'API au fil du temps (et c'est l'une des raisons pour lesquelles le fichier node.js a été créé). IIRC Ruby adopte toujours une approche beaucoup plus conservatrice à cet égard.

1
kazuho

V8 est rapide en raison du JIT, du vilebrequin, du type inferencer et du code optimisé pour les données. Pointeurs tagués, NaN-tagging des doubles. Et bien sûr, il effectue des optimisations normales du compilateur au milieu.

Les moteurs simples Ruby, python et Perl ne font rien de tout cela, 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 repliement constant, de marquage NaN ni d’entiers, mais utilise un code et des structures de données similaires, pas aussi gros que les mauvais langages. Et mes prototypes de langages dynamiques, potion et p2 ont des fonctionnalités similaires à celles de luajit et dépassent les performances de la v8. Avec un système de type optionnel, "typage progressif", vous pouvez facilement surpasser v8, car vous pouvez contourner le vilebrequin. Voir Dart.

Les serveurs optimisés connus, tels que pypy ou jruby, souffrent encore de diverses techniques de sur-ingénierie.

1
rurban