How to make a high-resolution setInterval in Node with It's possible in browser with just setInterval
I want to make an real-time application for working with serial on 250Hz speed For this I need to have clean intervals with duration below 5ms
function measure(setTimeout, time) {
let i = 0, a = new Float64Array(10_000), p = Promise.withResolvers();
let start = performance.now();
let lastNow = start;
function loop() {
let now = performance.now();
a[i++] = now - lastNow;
if (now - start > time) {
p.resolve(a.slice(1, i-1).sort().reverse())
} else {
lastNow = now;
setTimeout(loop);
}
}
loop();
return p.promise;
}
Promise.withResolvers ??= (o={})=>Object.assign(o,{promise:new Promise((r,j)=>{o.resolve=r;o.reject=j})})
measure(f => setTimeout(f, 1), 1000).then(a => console.log({
hz: a.length,
max: a[0],
'99%': a[~~(a.length*0.99)],
'95%': a[~~(a.length*0.95)],
'90%': a[~~(a.length*0.90)],
median: a[~~()],
a,
}))
// browser: {hz:216,max:6.3,99%:6.1,95:5.9,90:5.2,median:4.6} - fine
// node: {hz:69,max:16.3,99%:16.1,95:16,90:16.2,median:15.45} - I want better then this
// bun: {hz:61,max:32.3,99%:32.1,95:17.8,90:16.2,median:15.45} - I want better then this
How to make a high-resolution setInterval in Node with It's possible in browser with just setInterval
I want to make an real-time application for working with serial on 250Hz speed For this I need to have clean intervals with duration below 5ms
function measure(setTimeout, time) {
let i = 0, a = new Float64Array(10_000), p = Promise.withResolvers();
let start = performance.now();
let lastNow = start;
function loop() {
let now = performance.now();
a[i++] = now - lastNow;
if (now - start > time) {
p.resolve(a.slice(1, i-1).sort().reverse())
} else {
lastNow = now;
setTimeout(loop);
}
}
loop();
return p.promise;
}
Promise.withResolvers ??= (o={})=>Object.assign(o,{promise:new Promise((r,j)=>{o.resolve=r;o.reject=j})})
measure(f => setTimeout(f, 1), 1000).then(a => console.log({
hz: a.length,
max: a[0],
'99%': a[~~(a.length*0.99)],
'95%': a[~~(a.length*0.95)],
'90%': a[~~(a.length*0.90)],
median: a[~~()],
a,
}))
// browser: {hz:216,max:6.3,99%:6.1,95:5.9,90:5.2,median:4.6} - fine
// node: {hz:69,max:16.3,99%:16.1,95:16,90:16.2,median:15.45} - I want better then this
// bun: {hz:61,max:32.3,99%:32.1,95:17.8,90:16.2,median:15.45} - I want better then this
Share
asked Feb 11 at 11:05
DimavaDimava
10.9k1 gold badge12 silver badges31 bronze badges
1 Answer
Reset to default 0You may get precise timeouts using setImmediate I'm not yet sure it won't be heavy on CPU time it's but at least it works
function setTimeoutPrecise(callback, time) {
const start = performance.now()
loop()
function loop() {
if (performance.now() - start >= time) {
callback()
}
else {
setImmediate(loop)
}
}
}
node: {
hz: 985,
max: 9.391000000000005,
'99%': 1.0891000000000304,
'95%': 1.011099999999999,
'90%': 1.0066999999999666,
median: 1.0028999999999542,
}
bun: {
hz: 980,
max: 4.150199999999998,
"99%": 1.8109999999999218,
"95%": 1.0130000000000052,
"90%": 1.0060999999999964,
median: 1.0013000000000147,
}