答案 0 :(得分:4)
根据Don Syme等人撰写的“Expert F#”,F#进行尾调用优化。我似乎记得在Eric Lippert的博客上读到C#编译器(任何版本)都没有。如果我错了,请纠正我,埃里克。在所有情况下,当最后一条指令要调用方法时,可以进行尾调用优化。这通常是方法本身的递归调用,但不是必须的。可以完成优化,因为它保证不再需要当前的堆栈帧。但是,如果之后只需执行简单操作,则无法执行优化。
int Fib(int n)
{
if(n < 2)
return 1;
return Fib(n-1) + Fib(n-2);
}
这不能进行尾调用优化,因为在+
的最后一次调用返回之前无法评估Fib
。 (实际上我认为这是专家F#中使用的例子,但不确定那个。)
int Fib(int n, int a, int b)
{
if(n == 0)
return a+b;
return Fib(n-1,a+b,a);
}
此版本可以进行尾调用优化,因为在最后一次调用Fib之前评估所有参数,并且在调用之后不存在要执行的操作,因此可以丢弃当前堆栈帧。