Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
递归函数vs setInterval vs setTimeout javascript_Javascript_Performance_Recursion_Settimeout_Setinterval - Fatal编程技术网

递归函数vs setInterval vs setTimeout javascript

递归函数vs setInterval vs setTimeout javascript,javascript,performance,recursion,settimeout,setinterval,Javascript,Performance,Recursion,Settimeout,Setinterval,我正在使用NodeJs,需要调用一个无限函数,但我不知道什么是最佳性能的最佳方法 递归函数 function test(){ //my code test(); } setInterval setInterval(function(){ //my code },60); 设置超时时间 function test(){ //my code setTimeout(test,60); } 我希望在不崩溃服务器的情况下获得最佳性能。我的代码有几个算术运算 非常感谢任何优化javascript性能的

我正在使用NodeJs,需要调用一个无限函数,但我不知道什么是最佳性能的最佳方法

递归函数

function test(){
//my code
test();
}
setInterval

setInterval(function(){
//my code
},60);
设置超时时间

function test(){
//my code
setTimeout(test,60);
}
我希望在不崩溃服务器的情况下获得最佳性能。我的代码有几个算术运算


非常感谢任何优化javascript性能的建议。

递归函数会导致堆栈溢出。那不是你想要的

您显示的
setInterval
setTimeout
方法相同,只是
setInterval
更清晰


我推荐
setInterval
。(毕竟,这就是它的目的。)

不确定要实现什么,但这里有一种使用递归的“安全”方法


如前所述,无休止的递归函数会导致堆栈溢出。时间触发的回调将在自己的上下文中执行,并具有清晰的堆栈

setInterval
对于通过递归
setTimeout
进行更精确的定期调用非常有用,但是,有一个缺点:即使引发了未捕获的异常,也会触发回调。这通常每60毫秒生成一个数字节长的日志条目,每天生成144000个条目。此外,重载的
setInterval
回调可能会导致脚本没有响应,甚至导致系统崩溃


如果未捕获任何异常,则在函数返回前立即执行递归
setTimeout
。它将保证从回调函数返回后,其他任务的时间范围与函数的执行时间无关。

请小心。。您的第一个代码将阻止JavaScript事件循环

在JS中,基本上类似于应该处理的函数列表。当您调用
setTimeout
setInterval
process.nextTick
时,您会将给定函数添加到此列表中,并在适当的时间到来时对其进行处理

在第一种情况下,您的代码永远不会停止,因此它永远不会让事件列表中的其他函数被处理

第二和第三种情况是好的。。有一点不同

如果您的函数需要处理10毫秒,则间隔将为60毫秒

  • 设置间隔的函数将按时间处理:0-10、60-70、120-130、。。。(因此,两次呼叫之间只有50毫秒的延迟)
  • 但使用setTimeout时,它将是:
    • 如果你先调用func:0-10,70-80,140-150,210-220
    • 如果您先调用setTimeout:60-70130-140200-210
因此,不同之处在于函数启动之间的延迟,这在一些基于时间间隔的系统中很重要,如游戏、拍卖、股票市场。。等等


祝您的递归好运:-)

//使用setInterval函数

setInterval(function(){Property=value;},1000);
1000ms=1秒; 属性,如样式、宽度等

假设中描述的“性能延迟”,我已尝试使用此简单脚本检查吞吐量方面是否存在任何差异:

间隔:

const max = 50;
const timer = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 100, 150, 200, 250, 300, 400, 500];

function crono(timer) {
  return new Promise(resolve => {
    const exit = [];
    let i = 0
    setInterval(() => i++, timer);

    setInterval(() => {
      exit.push(i);
      i = 0;
      if (exit.length === max) {
        const sum = exit.reduce((a, b) => (a + b), 0);
        const avg = sum / exit.length;
        console.log(`${timer} = ${avg}`);
        resolve(avg)
      }
    }, 1000);
  });
}

Promise.all(timer.map(crono)).then(process.exit);
const max = 50;
const timer = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 100, 150, 200, 250, 300, 400, 500];

function crono(timer) {
  return new Promise(resolve => {
    const exit = [];
    let i = 0

    const redo = () => {
      i++
      setTimeout(redo, timer);
    }

    setInterval(() => {
      exit.push(i);
      i = 0;
      if (exit.length === max) {
        const sum = exit.reduce((a, b) => (a + b), 0);
        const avg = sum / exit.length;
        console.log(`${timer} = ${avg}`);
        resolve(x)
      }
    }, 1000);

    redo();
  });
}

Promise.all(timer.map(crono)).then(process.exit);
超时:

const max = 50;
const timer = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 100, 150, 200, 250, 300, 400, 500];

function crono(timer) {
  return new Promise(resolve => {
    const exit = [];
    let i = 0
    setInterval(() => i++, timer);

    setInterval(() => {
      exit.push(i);
      i = 0;
      if (exit.length === max) {
        const sum = exit.reduce((a, b) => (a + b), 0);
        const avg = sum / exit.length;
        console.log(`${timer} = ${avg}`);
        resolve(avg)
      }
    }, 1000);
  });
}

Promise.all(timer.map(crono)).then(process.exit);
const max = 50;
const timer = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 100, 150, 200, 250, 300, 400, 500];

function crono(timer) {
  return new Promise(resolve => {
    const exit = [];
    let i = 0

    const redo = () => {
      i++
      setTimeout(redo, timer);
    }

    setInterval(() => {
      exit.push(i);
      i = 0;
      if (exit.length === max) {
        const sum = exit.reduce((a, b) => (a + b), 0);
        const avg = sum / exit.length;
        console.log(`${timer} = ${avg}`);
        resolve(x)
      }
    }, 1000);

    redo();
  });
}

Promise.all(timer.map(crono)).then(process.exit);
这是vith nodejs 8.11的输出:它在吞吐量方面没有显示任何差异:


递归
setTimeout
保证执行之间的延迟,
setInterval
不保证

让我们比较两个代码片段。第一个使用
setInterval

let i = 1;
setInterval(function() {
  func(i);
}, 100);
第二个使用递归
setTimeout

let i = 1;
setTimeout(function run() {
  func(i);
  setTimeout(run, 100);
}, 100);
对于
setInterval
,内部计划程序将每隔100ms运行
func(i)

func
调用
setInterval
之间的实际延迟小于代码中的延迟

这是正常的,因为
func执行所花费的时间“消耗”了部分时间间隔

有可能
func的
执行时间比我们预期的要长,并且需要超过100毫秒

在这种情况下,引擎等待
func
完成,然后检查调度程序,如果时间已到,则立即再次运行调度程序

在edge情况下,如果函数的执行时间始终大于
delay
ms,则调用将不会暂停


递归
设置超时
保证固定的
延迟
(此处为100ms)。

取决于您调用的函数。递归函数正确无误,请参见。但是调用上的setinterval呢?@Vorge,什么是“descarted”和什么是“call”?对不起,放弃了“递归函数”。在做了一些测试之后,我得出结论,设置超时是最好的。这样我们可以防止任何覆盖。欢迎使用堆栈溢出!这个问题是关于Node.js的,一种服务器端技术(不在浏览器中)。如果您认为
setInterval()
是“最佳性能的最佳选择”(如问题所问),请尝试解释为什么它的性能优于其他选项。祝你在网站上玩得愉快!这是最完整、最正确的答案,应该被国际海事组织接受。谢谢!我明白了,你说的是在函数中执行CCA10ms。但另一个显著的区别是:第一个示例(setInterval)不是立即执行,而是在60毫秒后执行。第二个示例(setTimeout)将立即执行,然后在调用函数test()时每60毫秒执行一次。