6

Is it possible to measure time gaps less than 1 milliseconds that is supported in all browsers i know of only one way which is in Chrome.

The chrome method : window.performance.now()

Currently i do FPS measurements in millisecond time spaces, but if less than 1ms passes i get infinity because the two numbers are rounded to nearest millisecond so they are the same value.

Does any one know a cross browser function calculate less than 1 millisecond time gaps in javascript?

Sir
  • 8,135
  • 17
  • 83
  • 146
  • 1
    JavaScript (currently) lacks sub-millisecond timers. – Diodeus - James MacFarlane Feb 21 '13 at 22:41
  • I would state no, since the Date object works with milliseconds at lowest level, but let me know if not. – philipp Feb 21 '13 at 22:41
  • possible duplicate of [Does javascript provide a high resolution timer?](http://stackoverflow.com/questions/6875625/does-javascript-provide-a-high-resolution-timer) – Bergi Feb 21 '13 at 22:48
  • @Bergi not true i provided one option how to do it already in my question :P the answers over there say its not possible at all. – Sir Feb 21 '13 at 22:55
  • Do you really need to measure µs/F instead of F/s? Approximating the value by counting frames in the last second (or ms for the last 10 or 100 frames) should be enough imho – Bergi Feb 21 '13 at 22:55
  • @Bergi the issue is it will suggest 0 ms parsed which means 1000 / 0ms is infinity causing the average FPS to be totally inaccurate. – Sir Feb 21 '13 at 22:56
  • Yes, I can see that issue. But you only want average FPS, not exact frame-to-frame timing, do you? – Bergi Feb 21 '13 at 23:06
  • You can't average fps!!! it is inverted from the linear value of time per frame. If you average time per frame, then compute the fps of that, it will be correct. – Steven Lu Mar 31 '13 at 19:10

3 Answers3

3

Here's how you get accurate measurements without an accurate timer, so long as what you're timing occurs often, which I'm hoping they do in your case.

Average/aggregate the imprecise measurements of the duration of your event. A snippet out of one of my projects:

        var start = Date.now();
        ... (stuff to be timed)
        var now = Date.now();

        if (DEBUG.enabled) {
            var profile_this_iter = now - start;
            profile += (profile_this_iter - profile) * 0.02;
        }

Each new value measures nudges your reading closer to it by a factor of 0.02. Obviously you'll want to tweak that a bit. This will allow you to read an average that hovers around 0.5ms if you read a duration of 1ms half the time and 0ms half the time (with a 1ms resolution timer).

This is obviously not a replacement for a proper higher resolution timer. But I use this simple algorithm to give my javascript projects a non-crappy FPS reading. You get a damping factor that you can tweak depending on if you want more accuracy or more immediate response to changes. Considering the simplicity of this one, you'd be hard pressed to find a more elegant algorithm to provide you a good representation without any improved input data. One of the ways to enhance it would be to adjust the approach factor (that 0.02 constant) based on the frequency of sampling itself (if that changes), this way a slower measured rate could be made to converge more quickly than with a fixed value.

Steven Lu
  • 41,389
  • 58
  • 210
  • 364
1

There is actually another way to calculate the fps, which may be a way to go around this issue. It is to count the actual number of frames in a second, which should be quite accurate, I think.

var fpsStart = new Date().getTime();
var fpsCounting = 0;
var fps = 0;
start_the_first_frame();

// Loop
function update(){
    do_time_consuming_stuff();
    fpsCounting++;
    var thisFrame = new Date().getTime();
    if(thisFrame - fpsStart >= 1000){
        fpsStart += 1000;
        fps = fpsCounting;
        fpsCounting = 0;
    }
    request_next_animation_frame();
}

P.S. just typed right here, not tested, may require slight changes.

I remember seeing a way like this in lwjgl tutorial...

Also as noted by @StevenLu, you can modify it to count the number of frames in 0.5 second and multiply the "fps" by two, or even shorter time (e.g. 0.25 second) so that the update of the fps value will be more frequent.

Alvin Wong
  • 12,210
  • 5
  • 51
  • 77
  • This is also a solid solution for the problem. This does more of a direct FPS computation by literally recording the count over an actual real second so it will provide an integer value for you which may be more helpful than an abstract floating point result. The weakness of this method is in the accuracy of measuring low rates (a 0.5 fps reading using this method would give you a reading that alternates between reading 1fps and 0fps where my method will show you 0.5, but mine would take significant time to converge!) – Steven Lu Feb 22 '13 at 05:06
  • I'll also mention that this algorithm also has a convenient tweakable parameter which is the rate of sampling, so you can for example count the number of frames over 0.5 second and double that number to produce an FPS reading. This would have half the precision but twice the responsiveness. – Steven Lu Feb 22 '13 at 05:10
0

High resolution time is available in Chrome 20, but you should be aware, that time resolution in JS depends on the browser, device and circumstances. It might vary between 4ms and 1000+ms

valentinas
  • 4,277
  • 1
  • 20
  • 27
  • Do you think the second statement is still valid? That article was blogged in 2008. – Bergi Feb 21 '13 at 23:03
  • @Bergi good point about article being from 2008, I did a quick search and there are couple of articles from 2010 and 2011 too about the same problem, so I think the statement is still valid. – valentinas Feb 21 '13 at 23:13
  • 1
    For example this article: http://www.headlondon.com/our-thoughts/technology/posts/the-accuracy-of-javascript-timing – valentinas Feb 21 '13 at 23:17
  • It's in Chrome, Firefox, and IE10. – Šime Vidas Feb 22 '13 at 02:48