ale*_*dez 11 javascript milliseconds setinterval node.js
对于即将推出的node.js项目,我需要定期执行各种内务处理任务.特别是一些任务每毫秒,其他任务每20毫秒(每秒50次),还有其他每秒.所以我考虑使用setInterval(),结果很有趣:许多函数调用都被跳过了.
我使用的基准如下:
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);
Run Code Online (Sandbox Code Playgroud)
有一个长秒计时器和一个短计时器可以使用变量调整short,在这种情况下为1毫秒.每秒我们打印短周期中预期刻度数与短计数器更新的实际次数之间的差异.
以下是短定时器为1 ms时的行为方式:
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
Run Code Online (Sandbox Code Playgroud)
跳过许多函数调用.这是10毫秒:
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
Run Code Online (Sandbox Code Playgroud)
更好,但每秒跳过大约一个函数调用.并持续20毫秒:
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
Run Code Online (Sandbox Code Playgroud)
最后100毫秒:
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
Run Code Online (Sandbox Code Playgroud)
在这种情况下,它跳过很少的呼叫(间隔在33秒后增加到2,在108秒后增加到3).
数字变化,但在运行之间出乎意料地保持一致:运行第一个1 ms基准三次在9267,9259和9253的10秒后产生延迟.
我没有找到这个特殊问题的参考资料.有很多引用的Ressig帖子和许多相关的JavaScript问题,但大多数人认为代码在浏览器中运行而不是在node.js中运行.
现在是一个可怕的问题:这里发生了什么?只是开玩笑; 显然正在跳过函数调用.但我没有看到这种模式.我认为长周期可能会阻止短周期,但在1 ms的情况下它没有任何意义.短周期函数调用不重叠,因为它们只是更新变量,而node.js进程即使在1 ms的短周期内也接近5%CPU.负载平均值虽然高,约为0.50.我不知道为什么一千个电话会给我的系统带来太多压力,因为node.js可以完美地处理更多客户端 ; 一定是真的,setInterval()是CPU密集型(或者我做错了).
一个显而易见的解决方案是使用较长的计时器对函数调用进行分组,然后多次运行短循环函数调用以模拟较短的计时器.然后使用长周期作为"扫帚车",使得在较低的间隔中错过任何呼叫.示例:设置20 ms和1000 ms setInterval()调用.1 ms呼叫:在20 ms回叫中呼叫20次.对于1000毫秒呼叫:检查20ms功能被呼叫的次数(例如47),是否进行任何剩余呼叫(例如3).但是这个方案会有点复杂,因为呼叫可能会以有趣的方式重叠; 它也不会是常规的,虽然它可能看起来像.
真正的问题是:使用setInterval()还是node.js中的其他定时器可以做得更好吗?提前致谢.
看看这个doc:http://nodejs.org/api/timers.html#timers_settimeout_callback_delay_arg
重要的是要注意,你的回调可能不会在几毫秒内被调用 - Node.js不能保证回调何时触发的确切时间,也不会触发排序事件.回调将被调用为尽可能接近指定的时间.
这是因为应用程序代码阻止了事件循环.所有计时器和I/O事件只能在nextTick.
您可以使用以下代码查看此行为:
setInterval(function() {
console.log(Date.now());
for (var i = 0; i < 100000000; i++) {
}
}, 1);
Run Code Online (Sandbox Code Playgroud)
尝试更改迭代次数并查看结果.
理想情况下,如果应用程序滴答将持续少于1毫秒,则将完全触发计时器.但这在实际应用中并不实用.
| 归档时间: |
|
| 查看次数: |
22973 次 |
| 最近记录: |