J26*_*261 10 javascript recursion performance settimeout setinterval
我正在使用NodeJs并需要调用无限功能,但我不知道什么是最佳性能.
递归函数
function test(){
//my code
test();
}
Run Code Online (Sandbox Code Playgroud)
的setInterval
setInterval(function(){
//my code
},60);
Run Code Online (Sandbox Code Playgroud)
的setTimeout
function test(){
//my code
setTimeout(test,60);
}
Run Code Online (Sandbox Code Playgroud)
我想要最好的性能而不会崩溃服务器.我的代码有几个算术运算.
感谢任何优化javascript性能的建议.
Jan*_*ůna 16
小心..你的第一个代码会阻止JavaScript事件循环.
基本上在JS中就像应该处理的函数列表.当你打电话setTimeout,setInterval或者process.nextTick你将给这个列表添加给定的功能,当正确的时间到来时,它将被处理..
第一种情况下的代码永远不会停止,因此它永远不会让事件列表中的其他函数被处理.
第二个和第三个案例是好的...有一点点差别.
如果你的功能需要处理10毫秒,间隔将是你的60毫秒..
所以区别在于你的功能启动之间的延迟,这在一些基于区间的系统中很重要,比如游戏,拍卖,股票市场......等.
祝你的递归好运:-)
Qua*_*one 10
如前所述,无限递归函数会导致堆栈溢出.时间触发的回调将在具有清除堆栈的自己的上下文中执行.
setInterval对于通过递归进行更准确的定期调用很有用setTimeout,但是,有一个缺点:即使抛出了未捕获的异常,也会触发回调.这通常每60毫秒产生几个字节长的日志条目,每天产生1'440'000个条目.此外setInterval,重负载的回调最终可能会导致无响应的脚本甚至是漏洞系统.
如果没有捕获到任何异常,则setTimeout在从函数返回之前不会执行递归立即递归.它将保证从回调函数返回后的其他任务的时间范围,而与函数的执行时间无关.
不知道你想要完成什么,但这是一种使用递归的"安全"方式... /sf/ask/1694607351/
/*
this will obviously crash... and all recursion is at risk of running out of call stack and breaking your page...
function recursion(c){
c = c || 0;
console.log(c++);
recursion(c);
}
recursion();
*/
// add a setTimeout to reset the call stack and it will run "forever" without breaking your page!
// use chrome's heap snapshot tool to prove it to yourself. :)
function recursion(c){
setTimeout(function(c){
c = c || 0;
console.log(c++);
recursion(c);
},0,c);
}
recursion();
// another approach is to use event handlers, but that ultimately uses more code and more resources
Run Code Online (Sandbox Code Playgroud)
递归setTimeout保证执行之间的延迟,而setInterval\xe2\x80\x93 则不然。
让\xe2\x80\x99s 比较两个代码片段。第一个使用setInterval:
let i = 1;\nsetInterval(function() {\n func(i);\n}, 100);\nRun Code Online (Sandbox Code Playgroud)\n\n第二个使用递归setTimeout:
let i = 1;\nsetTimeout(function run() {\n func(i);\n setTimeout(run, 100);\n}, 100);\nRun Code Online (Sandbox Code Playgroud)\n\n对于setInterval内部调度程序将func(i)每 100 毫秒运行一次。
func调用之间的实际延迟setInterval小于代码中的延迟!
那\xe2\x80\x99是正常的,因为执行\xe2\x80\x9c所花费的时间消耗了func's\xe2\x80\x9d间隔的一部分。
执行时间可能func's比我们预期的要长,并且需要超过 100 毫秒。
在这种情况下,引擎等待func完成,然后检查调度程序,如果时间到了,则立即再次运行它。
在边缘情况下,如果函数执行时间始终超过delay毫秒,则调用将完全不会暂停。
递归setTimeout保证固定delay(这里是100ms)。
递归函数会导致堆栈溢出。那不是你想要的。
setInterval您所展示的和方式setTimeout是相同的,只是setInterval更清晰。
我会推荐setInterval。(毕竟,这就是它的用途。)