ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

javascript – 尾调用优化递归函数

2019-08-23 16:34:48  阅读:161  来源: 互联网

标签:javascript tail-recursion


这是一个深度展平数组的函数

const deepFlatten = (input) => {
  let result = [];
  input.forEach((val, index) => {
    if (Array.isArray(val)) {
      result.push(...deepFlatten(val));
    } else {
      result.push(val);
    }
  });
  return result;
};

在讨论过程中,我被告知它不具有内存效率,因为它可能会导致堆栈溢出.

我在http://2ality.com/2015/06/tail-call-optimization.html读到我可能会重写它以便它被TCO编辑.

它会是什么样子,我怎么能测量它的内存使用情况?

解决方法:

当递归调用在forEach中时,您无法对其进行优化,因为为了应用TCO,编译器需要检查您是否保存了前一次调用的“状态”.在forEach的情况下,您确实保存当前位置的“状态”.

为了使用TCO实现它,您可以重写使用递归调用实现的foreach,它看起来像这样:

function deepFlattenTCO(input) {
  const helper = (first, rest, result) => {
    if (!Array.isArray(first)) {
      result.push(first);
      if (rest.length > 0) {
        return helper(rest, [], result);
      } else {
        return result;
      }
    } else {
      const [newFirst, ...newRest] = first.concat(rest);

      return helper(newFirst, newRest, result);
    }
  };

  return helper(input, [], []);
}

console.log(deepFlattenTCO([
  [1], 2, [3], 4, [5, 6, [7]]
]));

您可以看到,在每个返回中,执行的唯一操作是递归调用,因此,您不会在递归调用之间保存“状态”,因此编译器将应用优化.

标签:javascript,tail-recursion
来源: https://codeday.me/bug/20190823/1698951.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有