什么是尾递归消除?
Steve Yegge mentioned it in a blog post and I have no idea what it means, could someone fill me in?
Is it the same thing as tail call optimization?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
尾部调用消除是一种节省堆栈空间的优化。 它将函数call替换为goto。 尾递归消除是同样的事情,但增加了函数调用自身的约束。
基本上,如果函数
A
所做的最后一件事是return A(params...)
那么您可以消除堆栈帧的分配,而是设置适当的寄存器并直接跳转到函数体。考虑一个(想象的)调用约定,它传递堆栈上的所有参数并返回某个寄存器中的值。
某些函数可以编译为(用假想的汇编语言):
无论上面实际做了什么,它都会为每次调用函数占用一个全新的堆栈帧。 然而,由于除了返回之外,在对函数的尾部调用之后没有发生任何事情,因此我们可以安全地优化这种情况。
结果:
最终结果是一个等效的函数,可以节省大量堆栈空间,特别是对于导致大量递归调用的输入。
我的回答需要很多想象力,但我想你能明白我的意思。
Tail call elimination is an optimization that saves stack space. It replaces a function call with a goto. Tail recursion elimination is the same thing, but with the added constraint that the function is calling itself.
Basically, if the very last thing a function
A
does isreturn A(params...)
then you can eliminate the allocation of a stack frame and instead set the appropriate registers and jump directly into the body of the function.Consider an (imaginary) calling convention that passes all parameters on the stack and returns the value in some register.
Some function could compile down to (in an imaginary assembly language):
Whatever the above actually does, it takes up a whole new stack frame for each call to function. However, since nothing occurs after the tail call to function except a return we can safely optimize that case away.
Resulting in:
The end result is an equivalent function that saves a lot of stack space, especially for inputs that result in a large number of recursive calls.
There's a lot of imagination required in my answer, but I think you can get the idea.
来自此处:
来自维基百科:
from here:
from Wikipedia: