我在编写的递归算法中搜索问题。
此算法会在某些输入上抛出RangeError: Maximum call stack size exceeded
(在Chrome中)错误。但我追踪的调用堆栈大小只有6k-9k左右。
This test(from this SO answer)表示Chrome中的最大调用堆栈大小约为42k。
运行一些测试后,我发现,在递归函数上有参数似乎会降低可用的调用堆栈大小:
带参数:超过 ~31k 调用堆栈大小(Chrome,边缘约15k)
var recursionA = function(a, b) {
count++;
if (count < 100000) {
recursionA(a, b);
}
}
没有参数:超过 ~42k 的调用堆栈大小(Chrome,边缘约16.5k)
var recursionB = function() {
count++;
if (count < 100000) {
recursionB();
}
}
答案 0 :(得分:1)
答案 1 :(得分:1)
我只是创建另一个递归函数来调用递归函数并分割持续时间,这样你就不会最大化堆栈。下面是一个“callStackOptimizer”的例子,我刚刚写了一个关于复杂而昂贵的fizzbuzz游戏的编写方式,用更多功能的不可变风格编写,向您展示我的意思。
"use strict";
const isDivisibleBy = divisor => number => number % divisor === 0;
const isDivisibleBy3 = isDivisibleBy(3);
const isDivisibleBy5 = isDivisibleBy(5);
const isDivisibleBy3And5 = number => isDivisibleBy5(number) && isDivisibleBy3(number);
const rules = (bool1, bool2, bool3) => (value1, value2, value3) => number => {
switch (true){
case bool1(number):
return value1;
break;
case bool2(number):
return value2;
break;
case bool3(number):
return value3;
break;
default:
return number;
}
};
const gameConditions = rules(
isDivisibleBy3And5,
isDivisibleBy3,
isDivisibleBy5
);
const fizzBuzzResults = gameConditions(
"FizzBuzz",
"Fizz",
"Buzz"
);
const game = duration => value => (action, array = []) => {
if (duration > 0){
const nextValue = action(value);
return game(duration - 1)(value + 1)(action, array.concat(nextValue))
}
else {
return array
}
};
const callStackOptimizer = (duration, times = Math.ceil(duration/10000), result = []) => rules =>{
if (times > 0){
const value = duration/times;
const round = game(value)(value * times - value + 1)(rules);
return callStackOptimizer(duration - value , times - 1, result.concat(round))(rules)
}
else {
return result;
}
};
const playFizzBuzz = duration => callStackOptimizer(duration)(fizzBuzzResults);
console.log(playFizzBuzz(100000));