web-dev-qa-db-fra.com

Débordement de la pile d'optimisation de la récursivité de la queue ES6

Après avoir lu description du Dr Rauschmayer d'optimisation récursive des appels de queue dans es6, j'ai depuis essayé de recréer l'exécution 'zero-stack' de la fonction factorielle récursive qu'il détaille.

À l'aide du débogueur Chrome pour passer entre les cadres de pile, je constate que l'optimisation de la queue ne se produit pas et qu'un cadre de pile est créé pour chaque récursivité.

J'ai également essayé de tester l'optimisation en appelant la fonction sans le débogueur, mais en passant à la place 100000 à la fonction factorielle. Cela génère une erreur de "pile maximale", ce qui implique qu'elle n'est en fait pas optimisée.

Voici mon code:

const factorial = (n, acc = 1) => n <= 1 ? acc : factorial(n - 1, n * acc)
console.log( factorial(100000) )

Résultat:

Uncaught RangeError: Maximum call stack size exceeded
31
Sam Hanlan

V8, le moteur JavaScript dans Chrome, a pris en charge TCO pendant un certain temps, mais à partir de cette réponse mise à jour (novembre 2017), il ne le fait plus et à ce jour, il n'y a pas de développement actif sur TCO dans V8, et aucun n'est prévu. Vous pouvez lire les détails dans le bug de suivi V8 pour cela .

Le support TCO semble avoir atteint un niveau décent dans la V8 à un moment donné, mais est resté derrière un drapeau pour plusieurs raisons (problèmes de débogage, bogues). Mais ensuite, plusieurs choses se sont produites, notamment l'équipe V8 a soulevé des problèmes importants avec TCO et a fortement soutenu un changement de spécification appelé appels de queue syntaxiques (STC) qui nécessiterait que les appels de queue être marqué intentionnellement dans le code source (par exemple, return continue doThat();). Cette proposition est devenue inactive en juillet 2017, cependant. Toujours en juillet, sans travail de TCO, l'équipe V8 a supprimé le code de prise en charge du TCO de la source de TurboFan * car il serait autrement soumis à Bitrot. (Par exemple, devenir une douleur d'entretien et une source de bugs.)

Donc à l'heure actuelle (novembre 2017), il n'est pas clair que le TCO "invisible" sera jamais dans le V8, si une sorte de STC arrivera, ou quoi. La page d'état de la plate-forme Chrome pour cela indique des signaux publics "mixtes" de Mozilla (Firefox/SpiderMonkey) et Microsoft (Edge/Chakra) sur la prise en charge du TCO, que Safari expédie avec le TCO et que les développeurs Web sont "positif" sur la fonctionnalité. Nous verrons où nous allons à partir d'ici. Si n'importe où.

* (TurboFan = le compilateur JIT de pointe actuel dans V8, maintenant ils ont commuté de Full-Codegen [JIT] + Vilebrequin [optimisation agressive JIT] à Ignition [interprète +] et TurboFan [optimisation agressive) JIT])

49
T.J. Crowder

L'équipe V8 (moteur JS de Chrome) n'implémente pas le TCO pour le moment. Il est arraché des versions les plus récentes ( voir ce fil ).

Parmi les principaux navigateurs, seul Safari a réellement implémenté la fonctionnalité .

Dans Node.JS version 8 et versions ultérieures, le TCO n'est pas disponible .

Il peut y avoir un certain espoir que le TCO soit implémenté: lors d'une récente réunion WebAssembly , Google et tous les autres groupes présents étaient neutres ou positifs pour explorer davantage l'implémentation du TCO.

9
Luke Williams