Improve performance of timing method

578 Views Asked by At

I use this nodejs module to measure / profile how long parts of my application take to execute.

// polyfill for window.performance.now
var performance = global.performance || {}
var performanceNow =
  performance.now        ||
  performance.mozNow     ||
  performance.msNow      ||
  performance.oNow       ||
  performance.webkitNow  ||
  function(){ return (new Date()).getTime() }

// generate timestamp or delta
// see http://nodejs.org/api/process.html#process_process_hrtime
function hrtime(previousTimestamp){
  var clocktime = performanceNow.call(performance)*1e-3
  var seconds = Math.floor(clocktime)
  var nanoseconds = Math.floor((clocktime%1)*1e9)
  if (previousTimestamp) {
    seconds = seconds - previousTimestamp[0]
    nanoseconds = nanoseconds - previousTimestamp[1]
    if (nanoseconds<0) {
      seconds--
      nanoseconds += 1e9
    }
  }
  return [seconds,nanoseconds]
}

function clock(start) {
    if ( !start ) return hrtime();
    var end = hrtime(start);
    return Math.round((end[0]*1000) + (end[1]/1000000));
}

module.exports = clock;

Usage is pretty straight forward: time = benchmark(); to start counter and time = benchmark(time); to measure duration since the previous call.

This includes a polyfill for when my application need to run on the browser.

The function seems to work well but it severely (and ironically) affects performance, especially (and unsurprisingly) in Internet Explorer.

How can I make it quicker?

1

There are 1 best solutions below

1
On BEST ANSWER

You do a lot of extra calculations...

// polyfill for window.performance.now
var performance = global.performance || {}
var performanceNow =
  performance.now        ||
  performance.mozNow     ||
  performance.msNow      ||
  performance.oNow       ||
  performance.webkitNow  ||
  function(){ return (new Date()).getTime() }

function clock(start) {
    if ( !start ) return performanceNow();
    var end = performanceNow();
    return end - start;
}

module.exports = clock;

This code should give the same results. (Math.round is omitted)

All methods (performance.now & Date.getTime) return time in milliseconds. As far as I understand it is expected output.

performance now in some browsers(Chrome) could provide you additional sub-millisecond timepart, then returned value will be non-int

e.g.

> performance.now()
160693.10000000405

Also test the performance of time retrieving methods:

On chrome and on my computer Date.now() gives max speed, triples output of performance.now()

see https://jsperf.com/get-time-3482/1

          Date.now    performance.now
Chrome    10 MOps      3.5 MOps
Safari    10 MOps      7   MOps

If you do multiple runs or if you measure big time intervals, the extra nanosecond precition may not be required

Then you will end up with IE9+ code:

var now = Date.now;
function clock(start) {
    if ( !start ) return now();
    var end = now();
    return end - start;
}

module.exports = clock;

=====

Additional notes:

The performance of performance.now vs Date.now may and should differ on Intel vs AMD CPU

They are using different processor instructions to get time, please look here for some details, http://zeromq.org/results:more-precise-0mq-tests