I've been working with scripts making use of setInterval(fn,delay) function in my application and after reading about how setTimeout and JS work I encounter some weird results so I made a test: Here is the jsfiddle https://jsfiddle.net/jyq46uu1/2/
And the code as suggested:
var limit = 1000000000;
var intervals = 0;
var totalTime = new Date();
var startTime = new Date();
var uid = setInterval(
function () {
// final lap?
if (intervals == 9) clearInterval(uid);
for (i = 0; i < limit; i += 1) {
// just working the CPU
}
// reduce the iterations
limit = limit / 10;
intervals += 1;
console.log('Interval ' + intervals +' Time elapsed : ' + (new Date() - startTime));
// reset the time
startTime = new Date();
}, 250, 9);
Ok, from what I've red from http://ejohn.org/blog/how-javascript-timers-work/ Javascript make the timer calls for the function in setInterval even if the "thread is blocked", so if the function is still executing the call is just queued and so on and so on ... in my notebook that code produces this:
"Interval 1 Time elapsed : 4264"
"Interval 2 Time elapsed : 477"
"Interval 3 Time elapsed : 91"
"Interval 4 Time elapsed : 170"
"Interval 5 Time elapsed : 246"
"Interval 6 Time elapsed : 242"
"Interval 7 Time elapsed : 248"
"Interval 8 Time elapsed : 248"
"Interval 9 Time elapsed : 248"
Ok, if what I've red is true, by the time the first interval finished, ALL functions calls were in the queue ... in my script I'm reducing the work for every execution so every call should take fewer seconds than the previous one, BUT no matter how much iterations I set, the elapsed time always pick up the Interval pace after the 4th run. Maybe I got it wrong but if by the time 4264 all functions are already in the queue and are suppose to run immediately, they should show less time, right? ... if the 3th iteration displays 91 and the others are just behind they should take 91 or less. But this is not the case.
If you understand what is happening please explain it to me because I think I'm missing something.
I think the first time is not counting from the initial interval in the queue, but from the point where you set startTime.
Then the first timer is counting initialization time, environment creation, variables and timers allocation.
Try this modification:
var limit = 1000000000;
var intervals = 0;
var totalTime = new Date();
var startTime = false;
var uid = setInterval(
function () {
if (!startTime) startTime = new Date();
// final lap?
if (intervals == 9) clearInterval(uid);
for (i = 0; i < limit; i += 1) {
// just working the CPU
}
// reduce the iterations
limit = limit / 10;
intervals += 1;
console.log('Interval ' + intervals +' Time elapsed : ' + (new Date() - startTime));
// reset the time
startTime = new Date();
}, 250, 9);
Also, the first time takes longer probably because the function is being interpreted, then the subsequent times is being executed "compiled"/optimized by the Javascript JIT ( see https://en.wikipedia.org/wiki/Just-in-time_compilation ). Check out this code to see the proof
var limit = 1000000000;
var intervals = 0;
var totalTime = new Date();
var startTime = new Date();
var uid = setInterval(
function () {
startTime = new Date();
// final lap?
if (intervals == 9) clearInterval(uid);
for (i = 0; i < limit; i += 1) {
// just working the CPU
}
// reduce the iterations
limit = limit / 10;
intervals += 1;
console.log('Interval ' + intervals +' Time elapsed : ' + (new Date() - startTime));
// reset the time
startTime = new Date();
}, 250, 9);
the output:
Interval 1 Time elapsed : 3249
Interval 2 Time elapsed : 299
Interval 3 Time elapsed : 31
Interval 4 Time elapsed : 5
Interval 5 Time elapsed : 0
Interval 6 Time elapsed : 0
Interval 7 Time elapsed : 0
Interval 8 Time elapsed : 0
Interval 9 Time elapsed : 0
Interval 10 Time elapsed : 0
setInterval is not good measuring the time in which it should queue the next execution. I think this has to do with sleep()ing. It is not reliable if a process is taking the cpu and hanging it (like the for you do).
setInterval guarantees only this:
setInterval does not guarantee that some execution is going to happen before a determined time in the future. That depends on the current CPU usage.
The queuing and launching of queued functions depends also on current CPU usage.
Extra Common Advice If you need to execute a function periodically, I recommend this approach that guarantees a delay always greather than 250ms between executions
var t = false;
var fun = function() {
console.log("run");
t = setTimeout(fun, 250);
}
fun();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With