Steve Yegge l'a mentionné dans un blog post et je n'ai aucune idée de ce que cela signifie, quelqu'un pourrait me remplir? Est-ce la même chose que tail call optimization?Qu'est-ce que l'élimination de la récursivité de la queue?
Répondre
L'élimination d'appel de queue est une optimisation qui économise pile espace. Elle remplace une fonction appel avec un goto. élimination récursive de la queue est la même chose, mais avec la contrainte supplémentaire que la fonction appelle lui-même.
en fait, si la dernière chose fonction A
est return A(params...)
alors vous pouvez éliminer l'allocation d'un cadre de pile et au lieu de définir les registres appropriés et sauter directement dans le corps de la fonction. Envisager une convention d'appel (imaginaire) qui passe tous les paramètres de la pile et renvoie la valeur dans un registre.
Certaines fonctions pourraient compiler jusqu'à (dans un langage d'assemblage imaginaire):
function:
//Reading params B, C, & D off the stack
pop B
pop C
pop D
//Do something meaningful, including a base case return
...
//Pass new values for B, C, & D to a new invocation of function on the stack
push D*
push C*
push B*
call function
ret
Quelle que soit ce qui précède ne fait, il faut un nouveau cadre de pile entière pour chaque appel à la fonction. Cependant, puisque rien ne se produit après l'appel de la queue pour fonctionner, sauf un retour, nous pouvons optimiser ce cas en toute sécurité.
Entraînant:
function:
//Reading params B, C, & D off the stack (but only on the first call)
pop B
pop C
pop D
function_tail_optimized:
//Do something meaningful, including a base case return
...
//Instead of a new stack frame, load the new values directly into the registers
load B, B*
load C, C*
load D, D*
//Don't call, instead jump directly back into the function
jump function_tail_optimized
Le résultat final est une fonction équivalente qui permet d'économiser beaucoup d'espace de pile, en particulier pour les entrées qui donnent lieu à un grand nombre d'appels récursifs.
Il y a beaucoup d'imagination dans ma réponse, mais je pense que vous pouvez avoir l'idée.
de here:
» ... l'élimination de la récursion arrière est un cas particulier de l'élimination appel de queue dans lequel l'appel de la queue est un appel à la fonction elle-même Dans ce cas, le appel. peut être remplacé par un saut au début de la fonction après le déplacement des nouveaux arguments aux appropriés registres ou emplacements de la pile ... »
de Wikipedia:
» ... Quand une fonction est appelée, l'ordinateur doit « se souvenir » l'endroit où il a été appelé à partir, l'adresse de retour, afin qu'il puisse revenir à cet endroit avec le résultat une fois que la l'appel est terminé. Typiquement, ces informations sont sauvegardées sur la pile, une simple liste d'emplacements de retour dans l'ordre des heures auxquelles les emplacements d'appel qu'ils décrivent ont été atteints. Parfois, la dernière chose que fait une fonction après avoir terminé toutes les autres opérations est simplement d'appeler une fonction, éventuellement elle-même, et de renvoyer son résultat. Avec la récursion de queue, il n'est pas nécessaire de se souvenir de l'endroit d'où nous appelons - à la place, nous pouvons laisser la pile seule, et la nouvelle fonction appelée retournera son résultat directement à l'appelant d'origine. La conversion d'un appel vers une branche ou un saut dans un tel cas s'appelle une optimisation d'appel de fin. Notez que l'appel de queue ne doit pas apparaître lexicalement après toutes les autres instructions dans le code source; il est seulement important que son résultat soit immédiatement renvoyé, puisque la fonction appelante n'aura aucune chance de faire quoi que ce soit après l'appel si l'optimisation est effectuée .... "
- 1. somme de récursivité queue, puissance, gcd en prolog?
- 2. différence entre la récursivité structurelle et la récursivité accumulative
- 3. Est-ce que Ruby effectue l'optimisation de l'appel de la queue?
- 4. Éviter la récursivité
- 5. Quelle est la marque de troncature de queue sur iPhone?
- 6. Techniques de récursivité Perl?
- 7. Suppression d'éléments d'IDictionary avec la récursivité
- 8. C++ Insérer un arbre de recherche binaire via la récursivité
- 9. Python sched.scheduler dépasse la profondeur de récursivité maximale
- 10. regexp pour couper la queue en option
- 11. Stack déborde de la récursivité profonde dans Java?
- 12. Queue à état (ne montre que les nouvelles lignes de la dernière exécution)
- 13. Meilleure Rebol Syntaxe que la tête enlever la queue arrière (retirer le moule b)?
- 14. Implémentation personnalisée de la fonctionnalité "queue -f" dans C
- 15. Utilisation de tableaux avec récursivité
- 16. L'utilisation de beaucoup de récursion de queue à Erlang ralentit-elle?
- 17. Profondeur de suivi en récursivité
- 18. Modèle de visiteur et récursivité
- 19. Est-ce que Xcode pour l'iPhone élimine la récursivité des appels?
- 20. Comment utiliser le théorème Master pour décrire la récursivité?
- 21. La récursivité est-elle bonne dans SQL Server?
- 22. Fonctions de rappel Javascript et récursivité
- 23. Procédures stockées SQL Server: font-elles la queue?
- 24. C# Request Queue
- 25. Pourquoi la récupération de place est-elle requise pour l'optimisation des appels de queue?
- 26. Java "queue -f" wrapper
- 27. Sans utiliser la récursivité, comment une exception de dépassement de pile peut-elle être levée?
- 28. Régler la profondeur de récursivité maximale lors de la sérialisation un modèle Django avec clé étrangère à JSON
- 29. WSMQ Queue Limit
- 30. Porte coulissante avec une queue
joliment et clairement écrit –
Donc, est-ce la même chose que l'optimisation des appels de queue? –
Ouais, juste avec la contrainte ajoutée que l'appel est à la fonction dans laquelle il est originaire. Désolé, ce n'est pas parfaitement clair. –