Thursday 12 December 2013

Looking into the high resolution timer of node.js

In the nodejs core a high resolution timer can be found. It is a method of the global process object called hrtime.
When the method is called an array is returned:
$ node
> process.hrtime();
[ 31013, 815378921 ]
Well, that does not look too useful.
The official documentation states:
It is relative to an arbitrary time in the past. It is not related to the time of day and therefore not subject to clock drift. The primary use is for measuring performance between intervals.
So measuring the time between two events is the actual purpose. The first event is recorded via an call to process.hrtime():
var start = process.hrtime();
Then when a certain operation has been finished (using setTimeout to simulate this), process.hrtime is called again with the start marker as a parameter:
setTimeout(function() {
  var elapsed = process.hrtime(start);
  console.log(elapsed);
}, 1000);
Not the output looks like this:
[ 1, 14933877 ]
The first element in the array is the elapsed time in seconds, the second element is the additional time in nanoseconds.
So to get an actual useful value out of this array we have to do a little calculation:
var timeInMilliseconds = elapsed[0] * 1e3 + elapsed[1] / 1e6;
Now the result is something like 1014.96679.
Success!

 The complete code example:
var start = process.hrtime();

setTimeout(function() {
    var elapsed = process.hrtime(start);
    var timeInMilliseconds = elapsed[0] * 1e3 + elapsed[1] / 1e6;

    console.log(timeInMilliseconds);
}, 1000);
If you dont like to do the same operation over and over again there is a high resolution timer module on npm: https://npmjs.org/package/hirestime

Install via:
npm install hirestime

Invokation:
var hirestime = require('hirestime');

//startpoint of the time measurement
var getElapsed = hirestime();

setTimeout(function() {
    //returns the elapsed milliseconds
    console.log(getElapsed());
}, 1000);
Optionally a timeunit can be assigned:
var hirestime = require('hirestime');

//startpoint of the time measurement
var getElapsed = hirestime();

setTimeout(function() {
    //returns the elapsed seconds
    console.log(getElapsed(hirestime.S));
}, 1000);
Possible time units are:

  • hirestime.S the elapsed time in seconds 
  • hirestime.NS the elapsed time in nanoseconds 
  • hirestime.MS the elapsed time in milliseconds 
 The timeunit defaults to milliseconds.