同一操作在 nodejs 中的有限函数调用?
Limited function calls in nodejs on same operation?
我目前正在进行一些科学计算,只要至少有一个参数为假,我的基础计算循环就会通过递归调用一遍又一遍地执行。
目前我的 nodejs 服务器在第 905 - 915 次递归函数调用时停止。
奇怪的是,它没有崩溃,也没有输出任何错误。它只是停止做任何事情 -> 没有更多的日志等
这是节点为了避免溢出而采取的某种保护行为吗?
我已经为此苦苦挣扎了几个星期,同时试图用尽可能智能的软件来限制 "loops"。
感谢您的帮助和建议。
你好诺亚。
根据要求,我提供了一些我的实际代码的抽象
希望对您有所帮助。我不能把我的原始代码放在这里,因为它包含超过 1.5k 行——有很多要检查的。
但下面的例子涵盖了递归调用背后的基本逻辑。
// Contains objects which contain an array
// which represents the amount of the ex_obj terms
var amount = {
a:[10,10],
b:[7.5,7.5],
c:[2.5,2.5,2.5,2.5]
}
// Contains objects, which contain an array of other objects
// that represent some selection
// Each object in an array consists of different values per attribute per 1 amount
var ex_obj = {
a: [
{aa: 1.41, ab: 0.143, ac: 0.5},
{aa: 1.30, ab: 1.43, ac: 0.42}
],
b: [
{aa: 0.32, ab: 5.54, ac: 1.3},
{aa: 0.33, ab: 4.49, ac: 2.5}
],
c: [
{aa: 0.54, ab: 1.4, ac: 3.5},
{aa: 0.39, ab: 1.434, ac: 3.91},
{aa: 0.231, ab: 1.44324, ac: 2.91},
{aa: 0.659, ab: 1.554, ac: 3.9124},
]
}
// Here we have an object that represents
// the "to be" state which should be achieved
var should_be ={
aa: 14.534,
ab: 3.43,
ac: 5.534
}
function calculate(){
// Now we want to mulitply the amount object values with
// the ex_obj values
for(let prop in ex_obj){
for(let i = 0, i < ex_obj[prop].length, i++){
for(let propa in ex_obj[prop][i]){
// here every aa,ab,ac gets mulitplied with the
// contains of the amount obj for the matching
// propertyname
}
}
}
// the next step is to check if the sum of all ex_obj property
// child values per aa, ab and ac match the should_be propertie values
// if everything is above the should_be and not too high then the
// programm can stop here and print out the amount obj.
// if the sum of the ex_obj properties is too little
// compared to the should_be obj
// we need to check which property is too little
// e.g. aa is too little
// then we check where aa in the ex_obj per 1 value is
// the highest
// then we increment the matching amount property child
// and start calculate() again
// same procedure for - if something is too much
}
由于您的代码不完整,因此很难准确说明哪里出了问题。如果您超过节点的调用堆栈限制,您将得到一个异常,尽管 1000 次递归通常不是问题。
可能是您阻塞了 Node.js 事件循环。不直接调用递归函数,可以尝试调用
process.nextTick(function(){calculate()})
直接递归调用会导致栈溢出并不奇怪,但是,函数调用频繁会导致节点挂掉(顺便说一句,我不知道为什么会这样:( ).
例如,以下脚本在我的机器上以 1.6 GHz CPU 和 3.3 GiB 内存在大约 4k ~ 5k 循环时冻结,之后节点不断吞噬我的可用内存。
var i = 0;
function cal() {
console.log(++i);
process.nextTick(cal);
}
cal();
但如果我将 process.nextTick(cal);
更改为 setTimeout(cal, 0);
,一切正常。
至于你的问题,我认为你可以在你的脚本中使用类似 setTimeout(calculate, 100)
的东西来防止递归调用并稍微延迟它。
我目前正在进行一些科学计算,只要至少有一个参数为假,我的基础计算循环就会通过递归调用一遍又一遍地执行。
目前我的 nodejs 服务器在第 905 - 915 次递归函数调用时停止。
奇怪的是,它没有崩溃,也没有输出任何错误。它只是停止做任何事情 -> 没有更多的日志等
这是节点为了避免溢出而采取的某种保护行为吗?
我已经为此苦苦挣扎了几个星期,同时试图用尽可能智能的软件来限制 "loops"。
感谢您的帮助和建议。 你好诺亚。
根据要求,我提供了一些我的实际代码的抽象
希望对您有所帮助。我不能把我的原始代码放在这里,因为它包含超过 1.5k 行——有很多要检查的。 但下面的例子涵盖了递归调用背后的基本逻辑。
// Contains objects which contain an array
// which represents the amount of the ex_obj terms
var amount = {
a:[10,10],
b:[7.5,7.5],
c:[2.5,2.5,2.5,2.5]
}
// Contains objects, which contain an array of other objects
// that represent some selection
// Each object in an array consists of different values per attribute per 1 amount
var ex_obj = {
a: [
{aa: 1.41, ab: 0.143, ac: 0.5},
{aa: 1.30, ab: 1.43, ac: 0.42}
],
b: [
{aa: 0.32, ab: 5.54, ac: 1.3},
{aa: 0.33, ab: 4.49, ac: 2.5}
],
c: [
{aa: 0.54, ab: 1.4, ac: 3.5},
{aa: 0.39, ab: 1.434, ac: 3.91},
{aa: 0.231, ab: 1.44324, ac: 2.91},
{aa: 0.659, ab: 1.554, ac: 3.9124},
]
}
// Here we have an object that represents
// the "to be" state which should be achieved
var should_be ={
aa: 14.534,
ab: 3.43,
ac: 5.534
}
function calculate(){
// Now we want to mulitply the amount object values with
// the ex_obj values
for(let prop in ex_obj){
for(let i = 0, i < ex_obj[prop].length, i++){
for(let propa in ex_obj[prop][i]){
// here every aa,ab,ac gets mulitplied with the
// contains of the amount obj for the matching
// propertyname
}
}
}
// the next step is to check if the sum of all ex_obj property
// child values per aa, ab and ac match the should_be propertie values
// if everything is above the should_be and not too high then the
// programm can stop here and print out the amount obj.
// if the sum of the ex_obj properties is too little
// compared to the should_be obj
// we need to check which property is too little
// e.g. aa is too little
// then we check where aa in the ex_obj per 1 value is
// the highest
// then we increment the matching amount property child
// and start calculate() again
// same procedure for - if something is too much
}
由于您的代码不完整,因此很难准确说明哪里出了问题。如果您超过节点的调用堆栈限制,您将得到一个异常,尽管 1000 次递归通常不是问题。
可能是您阻塞了 Node.js 事件循环。不直接调用递归函数,可以尝试调用
process.nextTick(function(){calculate()})
直接递归调用会导致栈溢出并不奇怪,但是,函数调用频繁会导致节点挂掉(顺便说一句,我不知道为什么会这样:( ).
例如,以下脚本在我的机器上以 1.6 GHz CPU 和 3.3 GiB 内存在大约 4k ~ 5k 循环时冻结,之后节点不断吞噬我的可用内存。
var i = 0;
function cal() {
console.log(++i);
process.nextTick(cal);
}
cal();
但如果我将 process.nextTick(cal);
更改为 setTimeout(cal, 0);
,一切正常。
至于你的问题,我认为你可以在你的脚本中使用类似 setTimeout(calculate, 100)
的东西来防止递归调用并稍微延迟它。