npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@trickfilm400/nanotimer

v0.3.17

Published

A much higher accuracy timer object that makes use of the node.js hrtime function call.

Downloads

11

Readme

nanotimer

Current Version - 0.3.15

NPM

A much higher accuracy timer object that makes use of the node.js hrtime function call.

The nanotimer recreates the internal javascript timing functions with higher resolution.

Note

    1. With the normal timing functions, instead of dealing with the obscurities of multiple setTimeout and setInterval calls, now there is a concrete timer object, each of which can handle exactly 1 timeOut and setInterval task. This also means a reference is not needed to clear an interval since each timer object is unique.
    1. Timer objects use the non-blocking feature setImmediate for time counting and synchronization. This requires node v0.10.13 or greater
    1. Errors in timing are non-cumulative. For example when using the setInterval command, the timer counts and compares the time difference since starting against the interval length specified and if it has run past the interval, it resets. If the code had an error of 1 millisecond delay, the timer would actually count to 1001 milliseconds before resetting, and that 1 millisecond error would propagate through each cycle and add up very quickly! To solve that problem, rather than resetting the interval variable each cycle, it is instead incremented with each cycle count. So on the 2nd cycle, it compares to 2000 milliseconds, and it may run to 2001. Then 3000 milliseconds, running to 3001, and so on. This is only limited by the comparison variable potentially overflowing, so I somewhat arbitrarily chose a value of 8 quadrillion (max is roughly 9 quadrillion in javascript) before it resets. Even using nanosecond resolution however, the comparison variable would reach 8 quadrillion every 8 million seconds, or every 93.6ish days.

Usage


var NanoTimer = require('nanotimer');

var timerA = new NanoTimer();

Each nanotimer object can run other functions that are already defined. This can be done in 2 ways; with either a literal function object, or with a function declaration.

by function object

var NanoTimer = require('nanotimer');
var timerObject = new NanoTimer();


var countToOneBillion = function () {
    var i = 0;
    while(i < 1000000000){
        i++;
    }
};

var microsecs = timerObject.time(countToOneBillion, '', 'u');
console.log(microsecs);

or something like this:

by function declaration

var NanoTimer = require('nanotimer');

function main(){
    var timerObject = new NanoTimer();

    var microsecs = timerObject.time(countToOneBillion, '', 'u');
    console.log(microsecs);
}

function countToOneBillion(){
    var i = 0;
    while(i < 1000000000){
        i++;
    }
}

main();

Full example

var NanoTimer = require('nanotimer');

var count = 10;


function main(){
    var timer = new NanoTimer();

    timer.setInterval(countDown, '', '1s');
    timer.setTimeout(liftOff, [timer], '10s');



}

function countDown(){
    console.log('T - ' + count);
    count--;
}

function liftOff(timer){
    timer.clearInterval();
    console.log('And we have liftoff!');
}

main();

In the example above, the interval can also be cleared another way rather than having to pass in the timer object to the liftOff task.

Instead, it can be done by specifying a callback to setTimeout, since the timer object will exist in that scope. Like so:

timer.setTimeout(liftOff, '', '10s', function(){
    timer.clearInterval();
});

.setTimeout(task, args, timeout, [callback])

  • task
    • The function or task to run. Can be either a literal function object or reference to a function declaration.
  • args
    • An array of arguments to pass to task, or an empty string, '' , if there are none. Note, even a single argument must be passed as an element in an array.
    • Ex. ['someString', 5, someVariable]
  • timeout
    • The amount of time to wait before calling task. This is a string containing a non-zero integer concatenated with one of 4 possible unit specifiers.
    • Unit specifiers are:
      • s = seconds
      • m = milliseconds
      • u = microseconds
      • n = nanoseconds
    • Ex. '500s', '37u', '45n'
  • [callback]]
    • The optional callback function to execute after the timeout has triggered.
console.log("It's gonna be legen-wait for it...");

timerA.setTimeout(dary, '', '2s');

function dary(){
    console.log("dary!!");
}

.setInterval(task, args, interval, [callback])

  • task
    • The function or task to run. Can be either a literal function object or reference to a function declaration.
  • args
    • An array of arguments to pass to task, or an empty string, '' , if there are none. Note, even a single argument must be passed as an element in an array.
    • Ex. ['someString', 5, someVariable]
  • interval
    • The interval of time to wait between each call of task. This is a string containing a non-zero integer concatenated with one of 4 possible unit specifiers.
    • Unit specifiers are:
      • s = seconds
      • m = milliseconds
      • u = microseconds
      • n = nanoseconds
    • Ex. '500s', '37u', '45n'
    • Note:
      • If interval is specified as 0, the timer will run task as fast as possible.
      • This function is self correcting, error does not propagate through each cycle, as described above.
  • [callback]]
    • The optional callback function to execute after the timeout has triggered.
timerA.setInterval(task, '100m', function(err) {
    if(err) {
        //error
    }
});

.time(task, args, format, [callback])

  • task
    • The function or task to run. Can be either a literal function object or reference to a function declaration.
  • args
    • An array of arguments to pass to task, or an empty string, '' , if there are none. Note, even a single argument must be passed as an element in an array.
    • Ex. ['someString', 5, someVariable]
  • format
    • A single unit specifier indicating the format of the data to be returned.
    • Unit specifiers:
      • s = seconds
      • m = milliseconds
      • u = microseconds
      • n = nanoseconds
    • Ex. '500s', '37u', '45n'
  • [callback]
    • The optional callback function to execute after the time call has triggered.

Synchronous Example:


var runtimeSeconds = timerA.time(doMath, '', 'u');

function doMath(){
    //do math
}

Asynchronous Use:

To time something asynchronous, you only need to do these 3 things:

  1. create a small wrapper function around the asynchronous task.
  2. make the wrapper function take callback as a parameter.
  3. manually call the callback parameter inside the callback of the asynchronous task.

It's essentially a chain of callbacks, which is probably already familiar to you. Here's an example that times how long it takes to read a file. Suppose you're using node.js's fs.ReadFile, which is asynchronous, then create a wrapper like so:

var NanoTimer = require('nanotimer');
var fs = require('fs');

var timer = new NanoTimer();


timer.time(loadFile, '', 'u', function(time){
    console.log("It took " + time + " microseconds to read that file!");
});

function loadFile(callback){
    fs.readFile('testReadFile.js', function(err, data){
        if(err) throw err;
        console.log(data);

        callback();
    });
}

.clearInterval()

  • Clears current running interval
timer.clearInterval();

.clearTimeout()

  • Clears current running timeOut
timer.clearTimeout();

.hasTimeout()

  • Returns true if the timer currently has a scheduled timeout, or false otherwise
timer.hasTimeout();

Logging

  • Added preliminary logging feature. If a timer is created by passing in 'log', it will enable verbose logging from the timer, so you can figure out the real amount of time being taken for setTimeout or setInterval
  • Currently only works on setInterval, and displays the 'cycle time', or real interval time to demonstrate how error does not propagate. This will be further expanded on.

Tests

  • Test suite used is mocha.
  • Tests also require should
  • In order for the test to perform properly, the timeout must be altered.
  • I prefer running tests with mocha -R spec -t 10000

Performance

Version 0.3.1 brings about a potentially massive performance boost over previous versions.

Previous versions used a setImmediate loop running as fast as possible for checking when to execute, inside setTimeout and setInterval. In 0.3.1, this has changed when using an intervalTime (setInterval), or delayTime (setTimeout) that is longer than 25ms. Execution will be deferred to the standard javascript setTimeout, aimed for 25ms before scheduled execution, where the setImmediate loop will resume.

The assumed error of javascript's setTimeout is 25ms.

Below is a test case with setInterval set to 1 second.