Speeding Up Frame Rates For DHTML Animation in Win98 - DHTML Lab | 5 | WebReference

Speeding Up Frame Rates For DHTML Animation in Win98 - DHTML Lab | 5

Logo

Speeding Up Frame Rates For DHTML Animation in Win98
A Case Study



Time Values of SetTimeout(), SetInterval and Date()

The second parameter in both setTimeout() and setInterval() sets the delay in milliseconds. However as alluded to above, there are problems with this setting. Even if you set the delay below 55 ms, these methods can't give delays less than 55 ms in Win9x.

What may be more surprising is that settings above 55 do not correlate with desired delays except for setInterval() when run on NN. For both IE and NN on Win9x, setTimeout() only gives delays that are integer multiples of 55 ms. Settings 1-55 give 55 ms, 56-110 give 110 ms, 111-165 give 165 ms, and so on, limiting the choice of frame rates to 18, 9, 6, 4.5, 3.6,...etc, Hz. This stepping of rates is apparently due to Win9x timers that update to the 55 ms time slice precision of the computers system clock [3]. On IE, setInterval() behaves like setTimeout() does but on NN it does not. NN gives the delays you specify as long as the settings are above 55.

A correlation study of delay settings and actual delays of the setTimeout() and setInterval() methods can be done using the Date() object. Date() creation is relatively fast at about 0.1-0.5 ms [1]. However, measuring process delays with two Date() creations, one just before a process starts and one just after it ends, is again limited to the 55 ms precision of the computers clock on Win9x. To see this you can use an "empty" for() statement of increasing size as the processes to be timed and correlated loop size with the delays returned. In the code below, the loops variable is the number of iterations of the for() statement and delay represents the statement's execution time using two Date() creations.

    t1 = new Date();
    for(j=0;j<loops;j++);
    t2 = new Date();
    delay = t2-t1;
It turns out that the shortest returned delays never go between 0 and 50. Also, for larger and larger loop sizes, the delays come back as multiples of 55 (+/- 5). The values that I've seen are: 0, 50, 60, 110, 160, 170, 210, 220, 270, 280, 320, 340...
 to see this for yourself.
This means that individual process delays can't be measured with millisecond precision using Date() but they can be estimated for a group of identical or similar processes.

Say an actual individual process delay is 1 ms. If we place t1 = new Date() just before one hundred of these and t2 = new Date() just after, then a delay (= t1-t2) is returned. The estimate for each individual process is simply delay/100 ms-per-process. Now, if these processes start at the beginning of a time slice, and we overlap two of them, then the delay returned would be 55 (actually 50 or 60) and the individual estimated delay would be 0.55 ms. On the other hand, if they started further in a time slice, and we overlap three of them, then the delay returned would be 110 giving an individual delay of 1.1 ms. The error in the individual estimate would be either 0.45 ms or 0.1 ms. If this error is too large then simply increase the number of processes measured.

Since we're dealing with processes that are theoretically no faster than 1 ms, and looking for general patterns, this simple approach is quite adequate to correlate the delay setting with actual delays for both setTimeout() and setInterval().

For setTimeout() the test script looks like this:

function startTest() {
  ctr=0;
  departure = new Date();
  timerID = setTimeout("testIt()",setDelay);
}
function testIt() {
  if (ctr<n) {
    ctr++; 
    timerID = setTimeout("testIt()",setDelay);
  }
   else {
     arrival = new Date();
     upDate();
  }
}
function upDate() {
  delay = arrival - departure;
  // Stats and book keeping.
  // restart test if need be by calling startTest() or stop.
}

For setInterval() it looks like this:

function startTest() {
  ctr=0;
  departure = new Date();
  timerID = setInterval("testIt()",setDelay);
}
function testIt() {
  if (ctr<n) {ctr++;}
   else {
     arrival = new Date();
     clearInterval(timerID);
     upDate();
   }
}
function upDate() {
  delay = arrival - departure;
  // Stats and book keeping.
  // restart test if need be by calling startTest() or stop.
}

To run the tests just click below.

Morten Wang has examined the correlation between requested delay values and actual delays for the setInterval() method on Win95/98, WinNT, Win2K and Linux [4].

He found the same pattern. IE steps delay settings to a multiple of the lowest possible delay, the difference being the lowest delay possible between the operating systems. Again, with setInterval() in NN any setting larger than the lowest possible delay is actually what you get.

Two methods cancel the scheduled execution of the thread before the delay expires. The clearTimeout(timerID) method cancels the scheduled timerID = setTimeout() timer that's waiting to evaluate its expression. Just clearTimeout() is used when a name isn't assigned to setTimeout(). The clearInterval(timerID) method cancels the automatic expression evaluation rescheduling of timerID = setInterval().

The Windows 98 operating system limits all timer based JavaScript methods to the 55 ms precision of the computer's clock. These methods are rate-limiting on classic scripts so other techniques need to be looked at for speeding up animation loops.

Produced by Mark Szlazak and

All Rights Reserved. Legal Notices.
Created: July 11, 2000
Revised: July 11, 2000

URL: http://www.webreference.com/dhtml/column34/5.html