美文网首页
尾调用优化

尾调用优化

作者: 寻梦的尕柳 | 来源:发表于2016-12-16 16:50 被阅读139次

什么是尾调用

  • 尾调用(Tail Call)是函数式编程的一个重要概念,就是指某个函数的最后一步是调用另一个函数。
// 尾调用
function f(x){
  return g(x);
}
// 不属于尾调用, 调用函数g之后,还有赋值操作
function f(x){
  let y = g(x);
  return y;
}

// 不属于尾调用, 调用后还有操作,即使写在一行内
function f(x){
  return g(x) + 1;
}

// 不属于尾调用,下面的两个函数等同
function f(x){
  g(x);
}
function f(x){
  g(x);
  return undefined;
}

// 尾调用, 虽然尾调用没出现在函数尾部,但是只要是最后一步操作即可
function f(x) {
  if (x > 0) {
    return m(x)
  }
  return n(x);
}

尾调用优化

  • 函数调用会在内存形成一个“调用记录”,又称“调用帧”(call frame),保存调用位置和内部变量等信息。如果在函数A的内部调用函数B,那么在A的调用帧上方,还会形成一个B的调用帧。等到B运行结束,将结果返回到A,B的调用帧才会消失。如果函数B内部还调用函数C,那就还有一个C的调用帧,以此类推。所有的调用帧,就形成一个“调用栈”(call stack)。
  • 尾调用由于是函数的最后一步操作,所以不需要保留外层函数的调用帧,因为调用位置、内部变量等信息都不会再用到了,只要直接用内层函数的调用帧,取代外层函数的调用帧就可以了。
  • 只有不再用到外层函数的内部变量,内层函数的调用帧才会取代外层函数的调用帧,否则就无法进行“尾调用优化”。
// 不会进行尾调用优化,因为内层函数inner用到了外层函数addOne的内部变量one。
function addOne(a){
  var one = 1;
  function inner(b){
    return b + one;
  }
  return inner(a);
}

尾递归

  • 函数调用自身,称为递归。如果尾调用自身,就称为尾递归。
  • 递归非常耗费内存,因为需要同时保存成千上百个调用帧,很容易发生“栈溢出”错误(stack overflow)。但对于尾递归来说,由于只存在一个调用帧,所以永远不会发生“栈溢出”错误。
// 正常递归,复杂度 O(n)
function factorial(n) {
  if (n === 1) return 1;
  return n * factorial(n - 1);
}

// 尾递归,复杂度 O(1)
function factorial(n, total = 1) {
  if (n === 1) return total;
  return factorial(n - 1, n * total);
}

来源: http://es6.ruanyifeng.com/#docs/function#尾调用优化

相关文章

  • 什么是尾调用?什么是尾递归?尾调用的优化?尾递归优化?

    尾调用优化 尾递归(尾调用优化)

  • 尾调用 & 尾递归 & 尾调用优化

    参考 递归和栈帧的调用原理[https://blog.csdn.net/poiuyds/article/detai...

  • 尾递归优化

    “尾递归优化”的含义是:如果递归函数属于尾递归,那么运行时会优化其调用过程。优化主要针对调用栈,将多层调用,转化为...

  • 尾调用优化

    所谓尾调用,就是指某个函数的最后一步是调用另一个函数。 这里有一个隐含要求,就是最后一步只能是单纯的函数调用,不能...

  • 尾调用优化

    什么是尾调用 尾调用(Tail Call)是函数式编程的一个重要概念,就是指某个函数的最后一步是调用另一个函数。 ...

  • 尾调用优化

    尾调用优化 尾递归 正常递归 尾递归 改写以上代码,使其只有一个参数: 总结一下,递归本质上是一种循环操作。纯粹的...

  • 尾调用优化

    什么是尾调用优化? 尾调用优化是指你可以避免重新分配给一个函数新的堆栈因为正在调用的函数会简单的返回它从已经调用过...

  • 尾调用优化

    1.尾调用是什么 尾调用指某个函数的最后一步是调用另一个函数。 错误例子: 1.递归优化 例: 说明:同样是阶乘,...

  • 尾调用优化

    Tail Call Optimization 出现在另一个函数“结尾”的函数调用。这个调用结束后就没有其他事情要做...

  • 尾调用,尾递归优化

    函数调用会在内存形成一个“调用记录”,又称“调用帧”(call frame),保存调用位置和内部变量等信息。如果在...

网友评论

      本文标题:尾调用优化

      本文链接:https://www.haomeiwen.com/subject/hxnnmttx.html