javascript – 尾调用优化递归函数
作者:互联网
这是一个深度展平数组的函数
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