timer - Javascript setTimeout unexpected output -
i've been working scripts making use of setinterval(fn,delay) function in application , after reading how settimeout , js work encounter weird results made test: here jsfiddle https://jsfiddle.net/jyq46uu1/2/
and code 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); (i = 0; < limit; += 1) { // working cpu } // reduce iterations limit = limit / 10; intervals += 1; console.log('interval ' + intervals +' time elapsed : ' + (new date() - starttime)); // reset time starttime = new date(); }, 250, 9);
ok, i've red http://ejohn.org/blog/how-javascript-timers-work/ javascript make timer calls function in setinterval if "thread blocked", if function still executing call queued , on , on ... in notebook 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 i've red true, time first interval finished, functions calls in queue ... in script i'm reducing work every execution every call should take fewer seconds previous one, no matter how iterations set, elapsed time pick interval pace after 4th run. maybe got wrong if time 4264 functions in queue , suppose run immediately, should show less time, right? ... if 3th iteration displays 91 , others behind should take 91 or less. not case.
if understand happening please explain me because think i'm missing something.
i think first time not counting initial interval in queue, point set starttime.
then first timer counting initialization time, environment creation, variables , timers allocation.
try 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); (i = 0; < limit; += 1) { // working cpu } // reduce iterations limit = limit / 10; intervals += 1; console.log('interval ' + intervals +' time elapsed : ' + (new date() - starttime)); // reset time starttime = new date(); }, 250, 9);
also, first time takes longer because function being interpreted, subsequent times being executed "compiled"/optimized javascript jit ( see https://en.wikipedia.org/wiki/just-in-time_compilation ). check out code see 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); (i = 0; < limit; += 1) { // working cpu } // reduce iterations limit = limit / 10; intervals += 1; console.log('interval ' + intervals +' time elapsed : ' + (new date() - starttime)); // reset 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 not measuring time in should queue next execution. think has sleep()ing. not reliable if process taking cpu , hanging (like do).
setinterval guarantees this:
- execution number 1 not going happen in less 250ms.
- execution number 2 not going happen in less 2*250ms ahead.
- execution number 3 not going happen in less 3*250ms ahead.
- ...
setinterval not guarantee execution going happen before determined time in future. depends on current cpu usage.
the queuing , launching of queued functions depends on current cpu usage.
extra common advice if need execute function periodically, recommend approach guarantees delay greather 250ms between executions
var t = false; var fun = function() { console.log("run"); t = settimeout(fun, 250); } fun();
Comments
Post a Comment