views:

82

answers:

5

Hello people. 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.

+2  A: 

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 http://stackoverflow.com/questions/2940054/how-to-determine-the-best-framerate-setinterval-delay-to-use-in-a-javascript .

smilingthax
A: 

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
I don't any browser supports a precision of 1ms. It seems to be 15ms for most browsers :)
Vivin Paliath
@Vivin, noted in the first paragraph. I left 1 in the second paragraph to try and avoid confusion for the OP.
JaredPar
@Jared Ah, didn't see that when I commented. Didn't reload the page. My bad!
Vivin Paliath
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
@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
+1  A: 

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

Please read this answer to see how setInterval works.

Marcel Korpel
+2  A: 

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
+1  A: 

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