除尾递归之外的尾调用优化?

时间:2013-08-03 18:55:12

标签: c++ c optimization compiler-construction tail-call-optimization

除了尾递归之外,是否还有可能进行尾调用优化?我一直试图找到或想到一个不涉及递归的,但没有成功。可能吗?有什么例子吗?

2 个答案:

答案 0 :(得分:3)

当然,“尾调用优化”实际上是这种优化的术语,它是最常见的递归不可知形式。此优化不会使用等效的while循环或类似的东西替换递归。而是转换尾部调用,以便重新使用调用者的堆栈帧。 return f(...)f(...); return形式的任何代码都可以修改。它适用于任何 f,即使对于函数指针/闭包/虚拟方法,编译器也不可能知道被调用的内容。因此,对于单独的编译,高阶函数,后期绑定等,它也可以更好地工作。

如果你看一下足够的代码,无论是功能性的还是命令性的,你都会偶尔看到一些没有任何代码的电话。一个常见的情况是,调用者委托被调用者执行主任务,并且只做一些额外的准备工作。在功能代码中,你经常会发现许多小函数只做一件事并且是用其他小函数实现的,所以你最后应用了一些简单的转换到参数,然后执行一个尾调用。下一层(将转换后的数据作为参数)。 TCO优化了第二步,它(理想情况下)使调用像简单的jump一样便宜,并使得漂亮的模块化代码占用的堆栈空间比单片实现更少。在面向对象的设计中,您可能希望组合其他对象的对象并公开委派的便捷方法:

SomeClass doSomething(Argument a) {
    log.debug("Doing something");
    return this.somethingDoer.doIt(a, this.someExtraData);
}

另一个技术上相互递归的例子,但通常只有很少的任何给定函数的激活(其间有数十或数百个其他激活),是通过每个状态具有一个函数并调用它进入该状态来实现的状态机:

void stateA() {
    // do actual work
    // determine which transition applies
    stateB();
}

void stateB() {
    // do actual work
    // determine which transition applies
    state...();
}

// dozens, possibly hundreds of other states

答案 1 :(得分:1)

int bar(int x);
int foo(int x) { return bar(x); }

foo可以直接跳转到直接返回来电者的bar;任何地方都不需要递归。