web-dev-qa-db-fra.com

La JVM empêche-t-elle les optimisations d'appel de fin?

J'ai vu cette citation sur la question: Quel est un bon langage fonctionnel sur lequel construire un service web?

Scala en particulier ne prend pas en charge l'élimination des appels de queue, sauf dans les fonctions auto-récursives, ce qui limite les types de composition que vous pouvez faire (c'est une limitation fondamentale de la JVM).

Est-ce vrai? Dans l'affirmative, qu'est-ce que la JVM crée cette limitation fondamentale?

98
Jason Dagit

Cet article: récursivité ou itération? pourrait aider.

En bref, l'optimisation des appels de queue est difficile à faire dans la machine virtuelle Java en raison du modèle de sécurité et de la nécessité de toujours disposer d'une trace de pile. Ces exigences pourraient en théorie être prises en charge, mais elles nécessiteraient probablement un nouveau bytecode (voir proposition informelle de John Rose ).

Il y a aussi plus de discussion dans Sun bug # 472634 , où l'évaluation (à partir de 2002) se termine:

Je pense que cela pourrait néanmoins être fait, mais ce n'est pas une mince tâche.

Actuellement, des travaux sont en cours dans le projet Da Vinci Machine . Le statut du sous-projet d'appel de queue est répertorié comme "proto 80%"; il est peu probable d'en faire Java 7, mais je pense qu'il a de très bonnes chances de Java 8.

74
Michael Myers

La limitation fondamentale est simplement que la JVM ne fournit pas d'appels de queue dans son code d'octet et, par conséquent, il n'y a aucun moyen direct pour un langage basé sur la JVM de fournir elle-même les appels de queue. Il existe des solutions de contournement qui peuvent produire un effet similaire (par exemple, le trampoline), mais elles se font au prix de graves performances et d'obscurcissement du code intermédiaire généré, ce qui rend un débogueur inutile.

La JVM ne peut donc prendre en charge aucun langage de programmation fonctionnel de qualité production tant que Sun n'a pas implémenté les appels de queue dans la JVM elle-même. Ils en discutent depuis des années mais je doute qu'ils implémenteront jamais des appels de queue: ce sera très difficile car ils ont optimisé prématurément leur VM avant d'implémenter de telles fonctionnalités de base, et l'effort de Sun est fortement concentré sur les langages dynamiques plutôt que sur les langages fonctionnels.

Il existe donc un argument très fort selon lequel Scala n'est pas un véritable langage de programmation fonctionnel: ces langages ont considéré les appels de queue comme une caractéristique essentielle depuis l'introduction de Scheme il y a plus de 30 ans.

27
Jon Harrop

Scala 2.7.x prend en charge l'optimisation des appels de queue pour l'auto-récursivité (une fonction qui s'appelle elle-même) des méthodes finales et des fonctions locales.

Scala 2.8 pourrait également prendre en charge la bibliothèque pour le trampoline, qui est une technique pour optimiser les fonctions mutuellement récursives.

De nombreuses informations sur l'état de la récursion Scala peuvent être trouvées dans le blog de Rich Dougherty .

21
Daniel C. Sobral

En plus du document lié dans Lambda The Ultimate (du lien mmyers publié ci-dessus), John Rose de Sun a encore plus à dire sur l'optimisation des appels de queue.

http://blogs.Oracle.com/jrose/entry/tail_calls_in_the_vm

J'ai entendu dire qu'il pourrait être implémenté un jour sur la JVM. Le support des appels de queue, entre autres, est envisagé sur la machine Da Vinci.

http://openjdk.Java.net/projects/mlvm/

8
faran

Toutes les sources indiquent que la machine virtuelle Java n'est pas en mesure d'optimiser dans le cas de la récursivité de la queue, mais à la lecture réglage des performances Java (2003, O'reilly), j'ai trouvé l'auteur affirmant qu'il pouvait obtenir de meilleures performances de récursivité en implémentant récursivité de la queue.

Vous pouvez trouver sa réclamation à la page 212 (recherchez "récursivité de la queue", cela devrait être le deuxième résultat). Ce qui donne?

0
fthinker