我使用的基准如下:
var counter = 0; var seconds = 0; var short = 1; setInterval(function() { counter ++; },short); setInterval(function() { seconds ++; log('Seconds: ' + seconds + ',counter: ' + counter + ',missed ' + (seconds * 1000 / short - counter)); },1000);
有一秒长的定时器和一个可以使用可变短路调整的短定时器,在这种情况下为1 ms.每隔一段时间,我们打印短周期内的预期滴答数与短计数器更新的实际次数之间的差额.
当短时间定时器为1毫秒时,它是如何工作的:
2012-09-14T23:03:32.780Z Seconds: 1,counter: 869,missed 131 2012-09-14T23:03:33.780Z Seconds: 2,counter: 1803,missed 197 2012-09-14T23:03:34.781Z Seconds: 3,counter: 2736,missed 264 ... 2012-09-14T23:03:41.783Z Seconds: 10,counter: 9267,missed 733
2012-09-14T23:01:56.363Z Seconds: 1,counter: 93,missed 7 2012-09-14T23:01:57.363Z Seconds: 2,counter: 192,missed 8 2012-09-14T23:01:58.364Z Seconds: 3,counter: 291,missed 9 ... 2012-09-14T23:02:05.364Z Seconds: 10,counter: 986,missed 14
2012-09-14T23:07:18.713Z Seconds: 1,counter: 46,missed 4 2012-09-14T23:07:19.713Z Seconds: 2,counter: 96,missed 4 2012-09-14T23:07:20.712Z Seconds: 3,counter: 146,missed 4 ... 2012-09-14T23:07:27.714Z Seconds: 10,counter: 495,missed 5
最后100 ms:
2012-09-14T23:04:25.804Z Seconds: 1,counter: 9,missed 1 2012-09-14T23:04:26.803Z Seconds: 2,counter: 19,missed 1 2012-09-14T23:04:27.804Z Seconds: 3,counter: 29,missed 1 ... 2012-09-14T23:04:34.805Z Seconds: 10,counter: 99,missed 1
在这种情况下,它跳过很少的通话(间隔在33秒后增加到2,在108秒后增加到3.
数字有所不同,但是在运行之间令人惊讶地一致:运行前1 ms基准三次,在9267,9259和9253的10秒后产生延迟.
我没有发现这个特定问题的引用.有这个much cited Ressig post和许多相关的JavaScript问题,但大多数假设代码在浏览器中运行,而不是在node.js.
现在对可怕的问题:这里发生了什么?开玩笑显然函数调用被跳过.但是我看不到这种模式.我认为长周期可能会阻止短周期,但在1 ms的情况下并没有任何意义.短周期功能调用不重叠,因为它们只是更新一个变量,即使在1 ms的短周期内,node.js进程也接近5%的cpu.负载平均水平虽高,约为0.50.我不知道为什么一千个电话会强调我的系统,但是,由于node.js处理many more clients perfectly;那肯定是setInterval() is CPU intensive(或者我做错了事情).
一个明显的解决方案是使用更长的定时器对功能调用进行分组,然后多次运行短周期函数调用,以模拟较短的定时器.然后使用较长的周期作为“扫帚车”,使得任何呼叫在较低的间隔内被错过.一个例子:设置20 ms和1000 ms setInterval()调用.对于1 ms调用:在20 ms回调中调用它们20次.对于1000ms呼叫:检查20ms功能被调用的次数(例如47),进行任何剩余呼叫(例如3).但是这个方案会有点复杂,因为呼叫可能会以有趣的方式重叠;它也不会是正常的,虽然它可能看起来像它.
真正的问题是:可以使用setInterval()还是node.js中的其他定时器来做得更好?提前致谢.