Aller au contenu principal

Retrait d'Octane

· 7 minutes de lecture
l'équipe V8

L'histoire des benchmarks JavaScript est une histoire d'évolution constante. Alors que le web est passé de simples documents à des applications dynamiques côté client, de nouveaux benchmarks JavaScript ont été créés pour mesurer des charges de travail devenues importantes pour de nouveaux cas d'utilisation. Ce changement constant a donné aux benchmarks individuels une durée de vie limitée. À mesure que les navigateurs web et les implémentations de machines virtuelles (VM) commencent à sur-optimiser pour des cas de test spécifiques, les benchmarks eux-mêmes cessent de devenir des proxies efficaces pour leurs cas d'utilisation d'origine. L'un des premiers benchmarks JavaScript, SunSpider, a fourni des incitations précoces à la livraison de compilateurs d'optimisation rapides. Cependant, à mesure que les ingénieurs des VM ont découvert les limitations des microbenchmarks et trouvé de nouvelles façons de optimiser autour des limites de SunSpider, la communauté des navigateurs web a retiré SunSpider en tant que benchmark recommandé.

La genèse d'Octane

Conçu pour pallier certaines des faiblesses des premiers microbenchmarks, le suite de benchmarks Octane a été initialement publié en 2012. Il a évolué à partir d'un ensemble précédent de simples cas de test V8 et est devenu un benchmark commun pour la performance générale du web. Octane est constitué de 17 tests différents, conçus pour couvrir une variété de charges de travail différentes, allant du test de simulation de noyau de Martin Richards à une version du compilateur TypeScript de Microsoft se compilant lui-même. Le contenu d'Octane représentait la sagesse dominante autour de la mesure de la performance JavaScript au moment de sa création.

Rendement décroissant et sur-optimisation

Dans les premières années suivant sa publication, Octane offrait une valeur unique à l'écosystème des machines virtuelles JavaScript. Il permettait aux moteurs, y compris V8, d'optimiser leur performance pour une classe d'applications qui mettaient l'accent sur les performances de pointe. Ces charges de travail intensives pour le CPU étaient initialement peu prises en charge par les implémentations de VM. Octane a aidé les développeurs des moteurs à fournir des optimisations qui permettaient aux applications lourdes en calcul d'atteindre des vitesses rendant JavaScript une alternative viable au C++ ou au Java. De plus, Octane a entraîné des améliorations dans la collecte des déchets, ce qui a permis aux navigateurs web d'éviter des pauses longues ou imprévisibles.

Cependant, dès 2015, la plupart des implémentations JavaScript avaient mis en œuvre les optimisations du compilateur nécessaires pour obtenir de bons scores sur Octane. Chercher à obtenir des scores encore plus élevés sur Octane s'est traduit par des améliorations de plus en plus marginales dans la performance des pages web réelles. Les enquêtes sur le profil d'exécution du chargement d'Octane par rapport au chargement de sites web communs (comme Facebook, Twitter ou Wikipédia) ont révélé que le benchmark n'exerce pas le analyseur de V8 ou la pile de chargement du navigateur comme le fait le code réel. De plus, le style JavaScript d'Octane ne correspond pas aux idiomes et aux modèles employés par la plupart des frameworks et des bibliothèques modernes (sans parler du code transpilé ou des nouvelles fonctionnalités du langage ES2015+). Cela signifie qu'utiliser Octane pour mesurer la performance de V8 ne capturait pas des cas d'utilisation importants pour le web moderne, comme charger rapidement des frameworks, prendre en charge de grandes applications avec de nouveaux modèles de gestion d'état ou garantir que les fonctionnalités ES2015+ soient aussi rapides que leurs équivalents ES5.

De plus, nous avons commencé à remarquer que les optimisations de JavaScript, qui amélioraient les scores Octane, avaient souvent un effet néfaste sur les scénarios réels. Octane encourage une optimisation agressive des fonctions pour minimiser les frais généraux des appels de fonctions, mais les stratégies d'optimisation adaptées à Octane ont entraîné des régressions en augmentant les coûts de compilation et l'utilisation de la mémoire dans des cas réels. Même lorsqu'une optimisation peut être réellement utile dans des cas réels, comme c'est le cas avec le prétenurage dynamique, la recherche de scores Octane plus élevés peut conduire à développer des heuristiques trop spécifiques qui ont peu d'effet ou dégradent les performances dans des cas plus génériques. Nous avons constaté que les heuristiques de prétenurage dérivées d'Octane entraînaient des dégradations de performance dans des frameworks modernes tels qu'Ember. L'opérateur instanceof était un autre exemple d'optimisation adaptée à un ensemble étroit de cas spécifiques à Octane, entraînant des régressions significatives dans les applications Node.js.

Un autre problème est qu'au fil du temps, des petits bugs dans Octane deviennent eux-mêmes une cible pour des optimisations. Par exemple, dans le benchmark Box2DWeb, exploiter un bug où deux objets étaient comparés avec les opérateurs < et >= donnait un gain de performance d'environ 15% sur Octane. Malheureusement, cette optimisation n'avait aucun effet dans le monde réel et complique les types d'optimisations de comparaison plus générales. Octane peut parfois même pénaliser négativement les optimisations réelles : les ingénieurs travaillant sur d'autres machines virtuelles ont remarqué qu'Octane semble pénaliser l'analyse paresseuse, une technique qui aide la plupart des sites web réels à se charger plus rapidement compte tenu de la quantité de code non utilisé fréquemment rencontré.

Au-delà d'Octane et des autres benchmarks synthétiques

Ces exemples ne sont que quelques-unes des nombreuses optimisations qui augmentaient les scores Octane au détriment de l'exécution de sites web réels. Malheureusement, des problèmes similaires existent dans d'autres benchmarks statiques ou synthétiques, y compris Kraken et JetStream. En termes simples, ces benchmarks sont des méthodes insuffisantes pour mesurer la vitesse réelle et incitent les ingénieurs à trop optimiser des cas spécifiques et sous-optimiser des cas génériques, ralentissant ainsi le code JavaScript dans le monde réel.

Compte tenu du plateau des scores à travers la plupart des machines virtuelles JS et du conflit croissant entre l'optimisation pour des benchmarks Octane spécifiques et l'implémentation d'accélérations pour une gamme plus large de code réel, nous pensons qu'il est temps de retirer Octane comme benchmark recommandé.

Octane a permis à l'écosystème JS de réaliser de grandes avancées dans le JavaScript coûteux en calcul. La prochaine frontière, cependant, consiste à améliorer la performance des pages web réelles, des bibliothèques modernes, des frameworks, des fonctionnalités linguistiques ES2015+ , des nouveaux modèles de gestion de l'état, de l' allocation immuable d'objets et du regroupement de modules bundling. Étant donné que V8 s'exécute dans de nombreux environnements, y compris côté serveur dans Node.js, nous investissons également du temps dans la compréhension des applications Node réelles et mesurons les performances JavaScript côté serveur à l'aide de charges de travail telles que AcmeAir.

Revenez ici pour plus de publications sur les améliorations de notre méthodologie de mesure et les nouvelles charges de travail qui représentent mieux les performances réelles. Nous sommes enthousiastes à l'idée de continuer à rechercher des performances qui comptent le plus pour les utilisateurs et les développeurs !