6

In using javascript i noticed this thing. You can use

var i=0; 
var startingTime=new Date().getTime();
setInterval("foo()",1);
function foo() {
    i+=1;
    if ($("#foodiv").text()==i) {
        //we detected a doubled value (parallel execution)
        $("#repdiv").append("[repetition on "+i+"]");
    }
    $("#foodiv").html(i);
    $("#timediv").html(Math.floor((new Date().getTime()-startingTime)/1000));
}

but as i read and try myself the time is not 1ms , it's at least 10ms or something. In fact after 10 seconds, i have a value of i around 2300/2400 , and not 10000 as expected.

This is the minimum possible time factor for the procedure ??? certainly NO. If i try this :

<html><head>
<script language="javascript" type="text/javascript" src="jquery-1.4.min.js"></script>
<script type="text/javascript">

var i=0;
var startingTime=new Date().getTime();

setInterval("foo()",1);setInterval("foo()",1);setInterval("foo()",1);
setInterval("foo()",1);setInterval("foo()",1);setInterval("foo()",1);
setInterval("foo()",1);setInterval("foo()",1);setInterval("foo()",1);
setInterval("foo()",1);setInterval("foo()",1);setInterval("foo()",1);
setInterval("foo()",1);setInterval("foo()",1);setInterval("foo()",1);
setInterval("foo()",1);setInterval("foo()",1);setInterval("foo()",1);
setInterval("foo()",1);setInterval("foo()",1);setInterval("foo()",1);
setInterval("foo()",1);setInterval("foo()",1);setInterval("foo()",1);

function foo() {
    i+=1;
    if ($("#foodiv").text()==i) {
        //we detected a doubled value (parallel execution)
        $("#repdiv").append("[repetition on "+i+"]");
    }
    $("#foodiv").html(i);
    $("#timediv").html(Math.floor((new Date().getTime()-startingTime)/1000));

}
</script>
</head>
<body>
<div id="foodiv"></div>  (counter)
<br/>
<div id="timediv"></div> (seconds passed)
<br/>
<div id="repdiv"></div>
<br/>
</body>
</html>

The counter will go very fast, and after 10 seconds, i have a value of 12000 !!!!. That's for me is unexplicable, because the call is not executed in parallel (or at least we could have some doubled readed values of i for different calls, figuring in the repdiv div).

Can someone explain me that ? I know the cpu is very stressed by all those calls, but at least it speed up things surprisingly.

I read all your responses and the other quests in the forum, and they confirmed my thinking. But the real question is Why ! Why they set the limit to 15ms when i can do multiple sequential calls obtaining a time much lower ? I'm sure this multiple callback system is not good practice, but i can do it, and i potentially can saturate cpu load.

mizar
  • 355
  • 4
  • 11
  • 5
    I dont see how this code works, set interval takes a function as the first argument, not foo(), it would have to be more like setInterval(foo, 1). Also you're missing some ending ) after your if and append – John Boker Oct 27 '10 at 21:13
  • Also, assuming the code is correct, the values seem wrong. With 12 timers, the counter will only go 12 times as fast, so 600 will become 7200, not 150000. Something tells me that this isn't the code that the OP tested. – casablanca Oct 27 '10 at 21:23
  • you're right, i edited the code many times, and recreated it at home, but the concept is not changing. I will repeat things as i did effectively. Also if you notice i omitted html code, and that make things worst if you try this as it is. – mizar Oct 27 '10 at 21:34
  • I completed my editing with a timestamp of seconds. – mizar Oct 27 '10 at 22:06
  • I completed my editing with a timestamp of seconds. Probably i accidentally discovered the way to bypass the 15ms limits imposed by javascript developers , in order to burn completely the cpu or lose instantly the notebook battery power ? I don't understand why in this case javascript is not alerting me of that thing. – mizar Oct 27 '10 at 22:12

5 Answers5

9

No, Javascript is single threaded. When you run setInterval or setTimeout, an event is generated which is then added to the browser's execution queue. So while you cannot guarantee that the code itself will run exactly when you want it to run, you can be sure that the event will be generated each time it is supposed to be generated. So in this case, you have 12 events that are being generated really close to each other. I notice that you've used 1 as the interval value. However, the minimum values in most browsers is around 15 (see here for more information.) The browser will run through the events in the order they are in the execution queue (in setInterval, the events try to play catch up. Look at the answer that Marcel linked to, for more details).

What this means is that in the first scenario you have one event generated every 15 or so milliseconds. So the counter is incremented more slowly. But in the second case, you have twelve events that are fired pretty close to each other every 15 or so milliseconds, and so the counter increments much faster.

Vivin Paliath
  • 94,126
  • 40
  • 223
  • 295
2

JavaScript timer values are set to at least 15ms in most browsers, even if a smaller value is given. AFAIK only Google Chrome uses 4ms. See also the accepted answer of How to determine the best "framerate" (setInterval delay) to use in a JavaScript animation loop? .

Community
  • 1
  • 1
smilingthax
  • 5,254
  • 1
  • 23
  • 19
1

No, JavaScript has no multithreading, at least not at the moment.

Please read this answer to see how setInterval works.

Community
  • 1
  • 1
Marcel Korpel
  • 21,536
  • 6
  • 60
  • 80
1

The code that you posted doesn't run, here is the corrected code:

var i=0; 
setInterval(foo,1);

function foo() {
  i+=1;
  if ($("#foodiv").text()==i) {
    //we detected a doubled value (parallel execution)
    $("#repdiv").append("[repetition on "+i+"]");
  }
  $("#foodiv").html(i);
}

If you look at the CPU performance while the code runs, you see that it's barely working at all, which means that the lower rate is not due to the code being busy. It simply won't fire the interval as often as you requested.

(If you start twelve intervals, the load is still barely noticable. I started 200 intervals before getting a load close to 100% on one of the cores.)

The browser uses some sort of clock to determine which intervals should be fired, and that clock usually has a lower resolution than milliseconds. So, the interval will not fire again until the next clock tick, which in your case seem to be about 15 ms apart.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
0

The second value passed to the setInterval method is indeed a minimum value. Although 1 represents 1 millisecond and it's unlikely that most browsers will give you exactly this timeout. Another answer says it's more likely to be around 15 milliseconds.

Even so, the second item being a minimum value adequetely explains the first sample.

The second sample is also explained by this behavior. Each of the setInterval methods you calls registers a completely separate call back. They each have a minimum of 1 but no dependency on each other. So it's perfectly valid for all of them to fire within the same 1 millisecond interval (as long as each one itself waits 1 millisecond before re-firing).

JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • I don't any browser supports a precision of 1ms. It seems to be 15ms for most browsers :) – Vivin Paliath Oct 27 '10 at 21:21
  • @Vivin, noted in the first paragraph. I left 1 in the second paragraph to try and avoid confusion for the OP. – JaredPar Oct 27 '10 at 21:26
  • Ah, didn't see that when I commented. Didn't reload the page. My bad! – Vivin Paliath Oct 27 '10 at 21:27
  • i don't get it. If this is a method to execute faster than 1ms and witohut parallel executions, as i see, because i is incremented without a single read valued repetition, i can't explain why code is not permitted to running faster. – mizar Oct 27 '10 at 22:03
  • @user489330, the reason why is that by calling setInterval multiple times you've said that the method `foo` can execute multiple times within the same interval – JaredPar Oct 27 '10 at 22:05