在我看来,在C和C++中进行尾递归优化是完美的,但是在调试时我似乎永远不会看到表示此优化的帧堆栈.这有点好,因为堆栈告诉我递归的深度.但是,优化也会很好.
是否有任何C++编译器进行此优化?为什么?为什么不?
我如何告诉编译器这样做?
/O2或/Ox-O2或-O3如何在某种情况下检查编译器是否已完成此操作?
我仍然会建议如何确定编译器是否对某个函数进行了优化(尽管我发现它让人放心,Konrad告诉我假设它)
总是可以通过进行无限递归来检查编译器是否完成此操作,并检查它是否导致无限循环或堆栈溢出(我用GCC做了这个并且发现这-O2已经足够了),但我想成为能够检查我知道的某个功能无论如何都会终止.我很想有一个简单的方法来检查这个:)
经过一些测试,我发现析构函数破坏了进行优化的可能性.有时可能值得更改某些变量和临时值的范围,以确保它们在return语句开始之前超出范围.
如果在尾调用后需要运行任何析构函数,则无法进行尾调用优化.
我尝试计算Ackermann(4,1),不同语言/编译器之间的性能差异很大.以下是我的Core i7 3820QM,16G,Ubuntu 12.10 64bit的结果,
C:1.6s,gcc -O3 (gcc 4.7.2)
int ack(int m, int n) {
if (m == 0) return n+1;
if (n == 0) return ack(m-1, 1);
return ack(m-1, ack(m, n-1));
}
int main() {
printf("%d\n", ack(4,1));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
OCaml:3.6s,ocamlopt (与ocaml 3.12.1)
let rec ack = function
| 0,n -> n+1
| m,0 -> ack (m-1, 1)
| m,n -> ack (m-1, ack (m, n-1))
in print_int (ack (4, 1)) …Run Code Online (Sandbox Code Playgroud) 在我的Ackermann功能的家庭工作中,我已经解决了以下问题
int main()
{
int y = ack(4,1);
cout<<"ans is :::: "<< y;
getch();
return 0;
}
int ack(int m, int n)
{
if(m == 0)
{
return n+1;
}
else if(m > 0 && n == 0)
{
return ack(m-1,1);
}
else if(m > 0 && n>0)
{
int x = ack(m,n-1);
return ack(m-1,x);
}
else
{
cout<< "did not worked properly";
}
}
Run Code Online (Sandbox Code Playgroud)
这个函数适用于低于m = 3和n = 10的低值但是当我给出m = 4 /更高或n = 15 /更高时,这不起作用.我没有出局.程序退出时没有任何警告或错误或结果.
请一些人告诉我这种情况发生的原因以及如何解决这个问题.
c++ ×2
optimization ×2
ackermann ×1
benchmarking ×1
c# ×1
f# ×1
haskell ×1
math ×1
performance ×1
recursion ×1