How to measure time taken by a function to execute

Viewed 1008374

I need to get execution time in milliseconds.

I originally asked this question back in 2008. The accepted answer then was to use new Date().getTime() However, we can all agree now that using the standard performance.now() API is more appropriate. I am therefore changing the accepted answer to this one.

30 Answers

Using performance.now():

var startTime = performance.now()

doSomething()   // <---- measured code goes between startTime and endTime
    
var endTime = performance.now()

console.log(`Call to doSomething took ${endTime - startTime} milliseconds`)

In Node.js it is required to import the performance class

importing performance

const { performance } = require('perf_hooks');

Using console.time: (living standard)

console.time('doSomething')
    
doSomething()   // <---- The function you're measuring time for 
    
console.timeEnd('doSomething')

Note:
The string being passed to the time() and timeEnd() methods must match
(for the timer to finish as expected).

console.time() documentations:

use new Date().getTime()

The getTime() method returns the number of milliseconds since midnight of January 1, 1970.

ex.

var start = new Date().getTime();

for (i = 0; i < 50000; ++i) {
// do something
}

var end = new Date().getTime();
var time = end - start;
alert('Execution time: ' + time);

Use Firebug, enable both Console and Javascript. Click Profile. Reload. Click Profile again. View the report.

A simple solution, you can use add operator also here

 var start = +new Date();
 callYourFunctionHere();
 var end = +new Date();
 var time = end - start;
 console.log('total execution time = '+ time + 'ms');

Here's a decorator for timing functions

It wraps functions so that they get timed each time they get run

Usage:

let test = () => { /* does something */ }
test = timed(test)   // turns the function into a timed function in one line
test()               // run your code as normal, logs 'function test took 1001.900ms' 

This is the decorator:

let timed = (f) => (...args) => {
    let start = performance.now();
    let ret = f(...args);
    console.log(`function ${f.name} took ${(performance.now() - start).toFixed(3)}ms`);
    return ret;   
}

If you're using async functions you can make timed async and add an await before f(...args), and that should work for those. It gets more complicated if you want one decorator to handle both sync and async functions.

It is possible to use only one variable:

var timer = -performance.now();

// Do something

timer += performance.now();
console.log("Time: " + (timer/1000).toFixed(5) + " sec.")

timer/1000 - to convert milliseconds to seconds

.toFixed(5) - to trim extra digits

there are multiple ways to achieve this objective :

  1. using console.time

    console.time('function');
    //run the function in between these two lines for that you need to 
    //measure time taken by the function. ("ex. function();")
    console.timeEnd('function');
    
  2. this is the most efficient way : using performance.now(), e.g.

    var v1 = performance.now();
    //run the function here for which you have top measure the time 
    var v2 = performance.now();
    console.log("total time  taken = "+(v2-v1)+"milliseconds");
    
  3. use +(add operator) or getTime()

    var h2 = +new Date(); //or
    var h2 = new Date().getTime();
    for(i=0;i<500;i++) { /* do something */}
    var h3 = +new Date();   //or 
    var h3 = new Date().getTime();
    var timeTaken = h3-h2;
    console.log("time ====", timeTaken);
    

Here's what happens when you apply the unary plus operator to a Date instance: Get the value of the Date instance in question Convert it to a Number

NOTE: getTime() gives better performance than unary + operator.

With performance

NodeJs: It is required to import the performance class

var time0 = performance.now(); // Store the time at this point into time0

yourFunction();   // The function you're measuring time for 

var time1 = performance.now(); // Store the time at this point into time1

console.log("youFunction took " + (time1 - time0) + " milliseconds to execute");

Using console.time

console.time('someFunction');

someFunction(); // Whatever is timed goes between the two "console.time"

console.timeEnd('someFunction');

Use console.time('some label here') before the function and console.timeEnd('some label here') after the function. It will give you the running time of the function.

Use this code format

const startTime =new Date().getTime();

//do something 
const endTime = new Date().getTime();
console.log(`time taken ${(endTime - startTime)/1000} seconds`);

Stopwatch with cumulative cycles

Works with server and client (Node or DOM), uses the Performance API. Good when you have many small cycles e.g. in a function called 1000 times that processes 1000 data objects but you want to see how each operation in this function adds up to the total.

So this one uses a module global (singleton) timer. Same as a class singleton pattern, just a bit simpler to use, but you need to put this in a separate e.g. stopwatch.js file.

const perf = typeof performance !== "undefined" ? performance : require('perf_hooks').performance;
const DIGITS = 2;

let _timers = {};

const _log = (label, delta?) => {
    if (_timers[label]) {
        console.log(`${label}: ` + (delta ? `${delta.toFixed(DIGITS)} ms last, ` : '') +
            `${_timers[label].total.toFixed(DIGITS)} ms total, ${_timers[label].cycles} cycles`);
    }
};

export const Stopwatch = {
    start(label) {
        const now = perf.now();
        if (_timers[label]) {
            if (!_timers[label].started) {
                _timers[label].started = now;
            }
        } else {
            _timers[label] = {
                started: now,
                total: 0,
                cycles: 0
            };
        }
    },
    /** Returns total elapsed milliseconds, or null if stopwatch doesn't exist. */
    stop(label, log = false) {
        const now = perf.now();
        if (_timers[label]) {
            let delta;
            if(_timers[label].started) {
                delta = now - _timers[label].started;
                _timers[label].started = null;
                _timers[label].total += delta;
                _timers[label].cycles++;
            }
            log && _log(label, delta);
            return _timers[label].total;
        } else {
            return null;
        }
    },
    /** Logs total time */
    log: _log,
    delete(label) {
        delete _timers[label];
    }
};

The best way would be to use the performance hooks module. Although unstable, you can mark specific areas of your code and measure the duration between marked areas.

const { performance, PerformanceObserver } = require('perf_hooks');

const measures = []

const obs = new PerformanceObserver(list => measures.push(...list.getEntries()));
obs.observe({ entryTypes: ['measure'] });
const getEntriesByType = cb => cb(measures);

const doSomething = val => {
  performance.mark('beginning of the process');

  val *= 2;

  performance.mark('after multiplication');

  performance.measure('time taken', 'beginning of the process', 'after multiplication');

  getEntriesByType(entries => {
    entries.forEach(entry => console.log(entry));
  })

  return val;
}

doSomething(4);

Try here

export default class Singleton {

  static myInstance: Singleton = null;

  _timers: any = {};

  /**
   * @returns {Singleton}
   */
  static getInstance() {
    if (Singleton.myInstance == null) {
      Singleton.myInstance = new Singleton();
    }

    return this.myInstance;
  }

  initTime(label: string) {
    this._timers[label] = Date.now();
    return this._timers[label];
  }

  endTime(label: string) {
    const endTime = Date.now();
    if (this._timers[label]) {
      const delta = endTime - this._timers[label];
      const finalTime = `${label}: ${delta}ms`;
      delete this._timers[label];
      return finalTime;
    } else {
      return null;
    }
  }
}

InitTime related to string.

return Singleton.getInstance().initTime(label); // Returns the time init

return Singleton.getInstance().endTime(label); // Returns the total time between init and end

In my case, I perfer to use @ grammar suger and compile it with babel.
The problem of this method is that function has to be inside object.

Sample JS Code

function timer() {
    return (target, propertyKey, descriptor) => {
        const start = Date.now();
        let oldFunc = descriptor.value;

        descriptor.value = async function (){
            var result = await oldFunc.apply(this, arguments);
            console.log(Date.now() - start);
            return result;
        }
    }
}

// Util function 
function delay(timeout) {
    return new Promise((resolve) => setTimeout(() => {
        resolve();
    }, timeout));
}

class Test {
    @timer()
    async test(timout) {
        await delay(timout)
        console.log("delay 1");
        await delay(timout)
        console.log("delay 2");
    }
}

const t = new Test();
t.test(1000)
t.test(100)

.babelrc (for babel 6)

 {
    "plugins": [
        "transform-decorators-legacy"
    ]
 }
  1. To start the timer use console.time("myTimer");
  2. Optional: To print the elapsed time, use console.timeLog("myTimer");
  3. Finally, to stop the timer and print the final time: console.timeEnd("myTimer");

You can read more about this on MDN and in the Node.js documentation.

Available on Chrome, Firefox, Opera and NodeJS. (not on Edge or Internet Explorer).

Basic TypeScript example that supports marks. Calling start('something') will begin the timer and stop('something') will end the timer and return a formatted string containing elapsed time.

View Flems Example

/**
 * Mark entries
 */
export const marks: { [id: string]: number } = {};

/**
 * Start timing 
 */
export const start = (id: string) => {
  return Object.assign(marks, {[id]: Date.now() })[id]
}

/**
 * Clear all 
 */
export const clear = () => {
  for (const id in marks) delete marks[id]; 
};

/**
 * Stop timing and return formatted elapsed time
 */
export const stop = (id: string) => {
  const ms = Date.now() - marks[id];
  delete marks[id];
  return ms > 1000 
    ? `${(ms / 1000).toFixed(0)}s ${+ms.toFixed(0).slice(1)}ms` 
    : `${ms.toFixed(0)}ms`;
};

The example code is exporting each function. You can drop this into a project and call the methods accordingly from a default as import, eg:

import * as time from './timer.js'

time.start('foo')

// do something

console.log('elapsed time: ' + time.stop('bar'))

You should also consider reading about bigO notation. It may be better than timing functions for understanding what is going on

Related