1710

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.

Donald Duck
  • 8,409
  • 22
  • 75
  • 99
Julius A
  • 38,062
  • 26
  • 74
  • 96
  • 5
    Often a statement on what you are trying to accomplish with the execution time can prove to be far more useful than answering the question alone. These days, using Profiling in Firebug or Chrome Dev tools is often a far better way of finding the code that is sucking up your cpu juice. – oligofren Mar 06 '13 at 10:04
  • 16
    `performance.now()` does not work in Node. `new Date().getTime()` will work in Node. – Ryan Walker Sep 11 '18 at 22:50
  • 2
    @RyanWalker or even more simple `Date.now()`, it is also works in node – f278f1b2 Nov 01 '19 at 15:18
  • 2
    @oligofren - Sometimes you may want to capture this data. I have a situation where I am writing this to indexedDB – ThomasRones Apr 08 '20 at 04:45
  • 1
    I was wondering is there any latest document (e.g. in 2020/201) saying performance.now() is better than Date.now() in node ? – Qiulang Apr 23 '21 at 07:00
  • For a **one-liner** that can be used on functions so they will log their execution time every time they're run, check out the answer below as well https://stackoverflow.com/a/52286301/3577695. It encapsulates the timing logic into a decorator to use it to "wrap" functions with it as needed – aljgom Nov 27 '21 at 11:45

30 Answers30

2671

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:

Noam Yizraeli
  • 4,446
  • 18
  • 35
vsync
  • 118,978
  • 58
  • 307
  • 400
  • 36
    It's supported by Chrome Developer Tools as well now. – julien_c Mar 15 '12 at 11:00
  • 4
    This is currently the best way to collect accurate timings from what I understand. – Ash Blue May 05 '12 at 02:18
  • 8
    Don't you need to execute the function between those two statements? You now measure the time it takes to define it, not to execute it. Correct me if I'm wrong... – Cristian Sep 04 '12 at 22:06
  • 2
    Link to the MDN article about this feature: https://developer.mozilla.org/en-US/docs/DOM/console.time – nullability Feb 19 '13 at 17:19
  • Is it possible to define a global timer on script start. Then get the difference between current time and script start in each step? – trante May 28 '13 at 15:03
  • @transte - yes, see Dayong's answer on the bottom – vsync May 28 '13 at 16:24
  • 1
    Is it possible to get the console.timeEnd() value? I'd like to sum multiple values. – Sam Dutton Jun 19 '13 at 14:34
  • 7
    yes you can do `totalTime += console.timeEnd('timer')' and do it for each timer – vsync Jun 19 '13 at 15:28
  • 1
    totalTime += console.timeEnd('timer') does not seem to work on Node. See my answer of how to make this work in Node. – Levi Roberts Aug 04 '13 at 04:24
  • 2
    BTW if you're working in Chrome - make sure you haven't inadvertently set the wrong log message filters. timeEnd() logs messages as "Debug" console messages. Sent me on a bit of a wild goose chase... – Ilan Oct 14 '13 at 14:16
  • This is good option but console.timeEnd() is still not a standard. Use Performance.now which is recommended. – Sanjeev Jan 25 '15 at 12:14
  • What factors determine this speed? `2 + 2` doesn't always yield the same time... Why? – Squirrl Apr 08 '15 at 07:16
  • 2
    @Squirrl - this thread is about measuring time, not "why" things are the way they are. That would be a matter for a whole new discussion. In short, the time different is because your CPU has cycles and not every time you run a command it devotes the same amount of resources to it. – vsync Apr 20 '15 at 21:04
  • @vsync Thanks! Is there a way to measure which cycle my CPU is in or the amount of resources devoted to my function, so that calling performance.now() or any method on 2+2 would yield the same time/power every time? I know this is a weird question. If I knew how to word it properly, I'd ask it formally. Thanks. http://jsfiddle.net/uzyk8poh/ – Squirrl Apr 22 '15 at 13:18
  • 1
    @Squirrl - don't think so. computers have way too many things being sent to the cpu every second. it's like sometimes 10 people are talking to you at the same time, and after a second, million. you cannot just tell everyone to shut up so you could focus on just one person, it's not like that. – vsync Apr 22 '15 at 13:52
  • 2
    Console.timeEnd in nodeJS returns `undefined`. –  Feb 24 '17 at 18:27
  • 3
    This is the current state of performance.now() `The timestamp is not actually high-resolution. To mitigate security threats such as Spectre, browsers currently round the result to varying degrees. (Firefox started rounding to 2 milliseconds in Firefox 59.) Some browsers may also slightly randomize the timestamp. The precision may improve again in future releases; browser developers are still investigating these timing attacks and how best to mitigate them.` – miknik Jul 14 '18 at 17:59
  • @miknik - `Date.now()` is good enough for most cases, and runs [much faster](https://jsperf.com/perf-vs-date/1). – vsync Jul 14 '18 at 18:25
  • 1
    @RyanWalker - yes it will, you simply need to require `performance`. see this [answer](https://stackoverflow.com/a/49348569/104380) – vsync Sep 12 '18 at 09:03
  • 1
    @vsync Yea it does if you're fine including more dependencies. I should have clarified that they don't work natively; I prefer minimal dependencies. – Ryan Walker Sep 12 '18 at 17:24
  • What if I run a function that is async? Such as jQuery's `$.getJSON()` function? – dcangulo Sep 17 '18 at 04:57
  • jQuery ajax function returns promises so you could calculate the differential time inside the [`always`](https://api.jquery.com/deferred.always) jQuery's promise method. I would suggest measuring the time it takes to fetch server data on the server itself, and only measure synced execution time on the client-side. anyway, if you are checking how long some very big function took to execute, then you need to change your mindset as to what exactly are you measuring and perhaps split your measurements into async and synced ones. – vsync Sep 17 '18 at 10:04
  • I created a useful lightweight module to do that - https://github.com/ngduc/mstime – ngduc Oct 04 '18 at 16:55
  • 1
    console.time is now a "living standard" (https://console.spec.whatwg.org/#time), and this answer should be updated to reflect that. – Johann Nov 14 '18 at 01:14
  • Multiple timers even with a different name seem to add up time. Can they be completely separated? – dari0h Jul 23 '20 at 15:11
  • const { performance } = require('perf_hooks'); // <-- Add import! – OnlyZero Jun 16 '21 at 15:57
  • For a **one-liner** that can be used on functions so they will log their execution time every time they're run, check out the answer below as well https://stackoverflow.com/a/52286301/3577695. It encapsulates the `timing` logic into a decorator to use it to "wrap" functions with it as needed – aljgom Nov 27 '21 at 11:33
  • don't forget, if you're timing in a test framework sometimes they will mock time functions, meaning you can't rely on either of these. – AncientSwordRage Nov 24 '22 at 17:48
  • Maybe someone would need to convert ms to hours:minutes:seconds format, so this function can be useful: `function msToTime(duration) { var ms = Math.floor((duration % 1000) / 100), secs = Math.floor((duration / 1000) % 60), mins = Math.floor((duration / (1000 * 60)) % 60), hs = Math.floor((duration / (1000 * 60 * 60)) % 24); hours = (hs < 10) ? "0" + hours : hours; minutes = (mins < 10) ? "0" + minutes : minutes; seconds = (secs < 10) ? "0" + seconds : seconds; return hours + ":" + minutes + ":" + seconds + "." + milliseconds; }` – maxxx Apr 29 '23 at 11:28
707

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);
Sam Watkins
  • 7,819
  • 3
  • 38
  • 38
Owen
  • 82,995
  • 21
  • 120
  • 115
  • 10
    Note that you can substitute +new Date() for the getTime() call: var start = +new Date(); // do stuff alert("Execution time: "+(+new Date())-start); – J c Nov 24 '08 at 13:00
  • 65
    Timings are not accurate because Date is not intended for this functionality. I'm going to be bold here and say you should use vsync's example if you want accurate timing. Although it only works in Chrome and Firefox ATM. – Ash Blue May 05 '12 at 02:17
  • 10
    Beware, the getMilliseconds() gives you the millisecond fraction of the current second. If you replace getTime() with getMilliseconds() you can get negative results if you cross a second. – RickyA Jan 10 '13 at 15:47
  • 7
    The answer by vsync is far more correct by todays standards, and using Date() can result in very erronous results being displayed, especially on the Windows platform where results may be rounded+floored to the nearest 15ms boundary, resulting in weird stuff such as 0ms timings on tiny code bits. – oligofren Mar 06 '13 at 09:59
  • 30
    @AshBlue, we should use `window.performance.now`. See http://stackoverflow.com/a/15641427/632951 – Pacerier Nov 02 '13 at 02:17
  • 2
    It should be noted that in NodeJS the console `time()` & `timeEnd` methods do use the `Date()` object. Source: https://github.com/joyent/node/blob/master/lib/console.js – Levi Roberts Dec 17 '13 at 19:27
  • 1
    While this is not correct to determine elapsed time of your code execution, I believe it works to compute elapsed time in other contexts. For example, I have a Node.js server which receives sensor signals, registers the event date with new Date(). Then I can compute the event's elapsed time with the method explained in this answer, for example. What do you guys think? – blaze Mar 08 '14 at 21:51
  • 1
    instead of 'var start = new Date().getTime();' and 'var end = new Date().getTime();' , we could use 'var start = Date.now();' and 'var end = Date.now();' avoiding (/ reducing) time differences that **could** occur by using 'Date().getTime()' because 'Date.now()' is much faster. – SoftwareTester Jun 04 '14 at 21:52
  • 2
    In fact, the use of `getTime()` (at least in modern JS engines) is unnecessary. Subtracting two `Date()` objects results in a number in milliseconds. – pbanka Aug 27 '15 at 17:02
  • 2
    This does not work if there are any callbacks in the function. – avishek gurung Jul 09 '16 at 06:49
  • 1
    Beware that the operation itself of creating a `new Date()` is costly, and can hurt the global performance a lot, for example when trying to time individual portions of a loop on a lot of items. – Thierry J. Oct 20 '17 at 12:39
  • 1
    All the answers here are incorrect and make an incorrect assumption that function execution time is constant for the same input. This was mostly true until around 2007. It ignores the fact all modern JS compilers in all modern browsers (and Node) have dead code elimination and just in time compilation. – Benjamin Gruenbaum Jun 06 '18 at 09:10
  • 1
    @ThierryJ. - creating Dates is much less "costly" than using `Performance.now` [see tests](https://jsperf.com/perf-vs-date/1) – vsync Sep 17 '18 at 10:26
  • 1
    That is very well possible. I'm just saying that if you create a date inside a loop you want to time, for the sole purpose of timing a part of that loop, the results will actually be worse than without the code to time the loop. – Thierry J. Sep 18 '18 at 14:48
459

Don't use Date(). Read below.

Use performance.now():

<script>
var a = performance.now();
alert('do something...');
var b = performance.now();
alert('It took ' + (b - a) + ' ms.');
</script>

It works on:

  • IE 10 ++

  • FireFox 15 ++

  • Chrome 24 ++

  • Safari 8 ++

  • Opera 15 ++

  • Android 4.4 ++

  • etc, etc

console.time may be viable for you, but it's non-standard §:

This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.

Besides browser support, performance.now seems to have the potential to provide more accurate timings as it appears to be the bare-bones version of console.time.


<rant> Also, DON'T EVER use Date for anything because it's affected by changes in "system time". Which means we will get invalid results —like "negative timing"— when the user doesn't have an accurate system time:

On Oct 2014, my system clock went haywire and guess what.... I opened Gmail and saw all of my day's emails "sent 0 minutes ago". And I'd thought Gmail is supposed to be built by world-class engineers from Google.......

(Set your system clock to one year ago and go to Gmail so we can all have a good laugh. Perhaps someday we will have a Hall of Shame for JS Date.)

Google Spreadsheet's now() function also suffers from this problem.

The only time you'll be using Date is when you want to show the user his system clock time. Not when you want to get the time or to measure anything.

Pacerier
  • 86,231
  • 106
  • 366
  • 634
  • 4
    Just what I was looking for! I want to be able to add several times together, can't really do that with console times. – Ray Sep 29 '13 at 13:33
  • 10
    note that this isn't supported in safari yet: https://developer.mozilla.org/en-US/docs/Web/API/Performance.now() – Akos K Nov 01 '13 at 21:11
  • 3
    I use Firebug Profile and performance.now(), and they both work well. Performance.now() confirms my result from Profile. – Vincent Jia Feb 11 '14 at 10:01
  • 3
    Doesn't work in my biggest hangup, which is IE7 (corporate customers.) I don't care about measuring performance in chrome, it's always lightning fast. – Nick Mar 03 '14 at 18:27
  • 3
    This is a better way then console.time(). – Sanjeev Jan 25 '15 at 12:15
  • 1
    Note: old implementations and polyfills use Date.now. –  Feb 24 '17 at 18:34
  • 1
    Doesn't work in Windows Script Hosting. So, gotta stick with getTime(). – HaLeiVi Feb 24 '17 at 22:02
  • 1
    Yes, this does work better, but Date.now() is used because Node.js (non-server) does not support the answer brought here or by vsync. – user8385393 May 19 '20 at 11:59
  • 1
    About your rant about `Date` - what would you recommend as an alternative? Sending the current date with your script obviously doesn't work and neither does fetching it because of network delay, so with what kind of solution did you come up? – Simon Sep 23 '20 at 06:36
65

If you need to get function execution time on your local development machine, you can either use your browser's profiling tools, or console commands such as console.time() and console.timeEnd().

All modern browsers have JavaScript profilers built-in. These profilers should give the most accurate measurement as you do not have to modify your existing code, which could affect the function's execution time.

To profile your JavaScript:

  • In Chrome, press F12 and select the Profiles tab, then Collect JavaScript CPU Profile.
  • In Firefox, install/open Firebug, and click on the Profile button.
  • In IE 9+, press F12, click on Script or Profiler (depending on your version of IE).

Alternatively, on your development machine, you can add instrumentation to your code with console.time() and console.timeEnd(). These functions, supported in Firefox11+, Chrome2+ and IE11+, report on timers that you start/stop via console.time(). time() takes a user-defined timer name as an argument, and timeEnd() then reports on the execution time since the timer started:

function a() {
  console.time("mytimer");
  ... do stuff ...
  var dur = console.timeEnd("myTimer"); // NOTE: dur only works in FF
}

Note that only Firefox returns the elapsed time in the timeEnd() call. The other browsers simply report the result to the developer console: the return value of timeEnd() is undefined.

If you want to get function execution time in the wild, you will have to instrument your code. You have a couple options. You can simply save the start and end times by querying new Date().getTime():

function a() {
  var start = new Date().getTime();
  ... do stuff ...
  var end = new Date().getTime();
  var dur = end - start;
}

However, the Date object only has millisecond resolution and will be affected by any OS's system clock changes. In modern browsers, there's a better option.

The better option is to use the High Resolution Time, aka window.performance.now(). now() is better than the traditional Date.getTime() in two important ways:

  1. now() is a double with submillisecond resolution that represents the number of milliseconds since the start of the page's navigation. It returns the number of microseconds in the fractional (e.g. a value of 1000.123 is 1 second and 123 microseconds).

  2. now() is monotonically increasing. This is important as Date.getTime() can possibly jump forward or even backward on subsequent calls. Notably, if the OS's system time is updated (e.g. atomic clock synchronization), Date.getTime() is also updated. now() is guaranteed to always be monotonically increasing, so it is not affected by the OS's system time -- it will always be wall-clock time (assuming your wall clock is not atomic...).

now() can be used in almost every place that new Date().getTime(), + new Date andt Date.now() are. The exception is that Date and now() times don't mix, as Date is based on unix-epoch (the number of milliseconds since 1970), while now() is the number of milliseconds since your page navigation started (so it will be much smaller than Date).

Here's an example of how to use now():

function a() {
  var start = window.performance.now();
   ... do stuff ...
  var end = window.performance.now();
  var dur = end - start;
}

now() is supported in Chrome stable, Firefox 15+, and IE10. There are also several polyfills available.

One other option for measuring execution time in the wild is UserTiming. UserTiming behaves similarly to console.time() and console.timeEnd(), but it utilizes the same High Resolution Timestamp that now() uses (so you get a sub-millisecond monotonically increasing clock), and saves the timestamps and durations to the PerformanceTimeline.

UserTiming has the concepts of marks (timestamps) and measures (durations). You can define as many of either as you want, and they're exposed on the PerformanceTimeline.

To save a timestamp, you call mark(startMarkName). To get the duration since your first mark, you simply call measure(measurename, startMarkname). The duration is then saved in the PerformanceTimeline alongside your marks.

function a() {
  window.performance.mark("start");
  ... do stuff ...
  window.performance.measure("myfunctionduration", "start");
}

// duration is window.performance.getEntriesByName("myfunctionduration", "measure")[0];

UserTiming is available in IE10+ and Chrome25+. There is also a polyfill available (which I wrote).

NicJ
  • 4,070
  • 1
  • 25
  • 18
  • 1
    Excellent and most current answer IMHO :) It would be even better with a bit of editing. I'd say that user timing is not "one other option" for measuring, but _the_ preferred option when the benchmarking is not done on the development machine itself. With your polyfill it works across all browsers. And hiding away the details and boilerplate of `performance.now` and `Date` is the reason it exists. – hashchange Jul 19 '14 at 10:10
39

To get precise values you should use Performance interface. It's supported in modern versions of Firefox, Chrome, Opera and IE. Here's an example of how it can be used:

var performance = window.performance;
var t0 = performance.now();
doWork();
var t1 = performance.now();
console.log("Call to doWork took " + (t1 - t0) + " milliseconds.")

Date.getTime() or console.time() are not good for measuring precise execution time. You can use them if quick rough estimate is OK for you. By rough estimate I mean you can get 15-60 ms shift from the real time.

Check this brilliant post on measuring execution time in JavaScript. The author also gives a couple of links about accuracy of JavaScript time, worth reading.

Aaron Hudon
  • 5,280
  • 4
  • 53
  • 60
Varvara Kalinina
  • 2,043
  • 19
  • 29
  • This works best because the accepted answer requires `node.js` and this answer does not. Coincidentally your total points `1,963` equals my birrth year! – WinEunuuchs2Unix Mar 09 '22 at 01:48
  • @WinEunuuchs2Unix Alas, your total points `1,382` means nothing special to me. Make it to `1,991` and give me five :) – Varvara Kalinina Mar 10 '22 at 12:46
21

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

Stefan Mai
  • 23,367
  • 6
  • 55
  • 61
21

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');
Alok Deshwal
  • 1,128
  • 9
  • 20
16

process.hrtime() is available within Node.js - it returns a value in nanoseconds

let hrTime = process.hrtime()
console.log(hrTime[0] * 1000000 + hrTime[1] / 1000)
Lukas Liesis
  • 24,652
  • 10
  • 111
  • 109
Achim Koellner
  • 913
  • 12
  • 22
  • 1
    if you rather convert it to ms e-3 rather than the suggested microsecond e-6: `hrtime[0] * 1000 + hrtime[1] / 1000000` -> yeah, I rather use `var hrtime` as well! :P – cregox Mar 25 '17 at 14:21
14

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.

aljgom
  • 7,879
  • 3
  • 33
  • 28
14

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

user1032559
  • 1,577
  • 1
  • 14
  • 16
13
var StopWatch = function (performance) {
    this.startTime = 0;
    this.stopTime = 0;
    this.running = false;
    this.performance = performance === false ? false : !!window.performance;
};

StopWatch.prototype.currentTime = function () {
    return this.performance ? window.performance.now() : new Date().getTime();
};

StopWatch.prototype.start = function () {
    this.startTime = this.currentTime();
    this.running = true;
};

StopWatch.prototype.stop = function () {
    this.stopTime = this.currentTime();
    this.running = false;
};

StopWatch.prototype.getElapsedMilliseconds = function () {
    if (this.running) {
        this.stopTime = this.currentTime();
    }

    return this.stopTime - this.startTime;
};

StopWatch.prototype.getElapsedSeconds = function () {
    return this.getElapsedMilliseconds() / 1000;
};

StopWatch.prototype.printElapsed = function (name) {
    var currentName = name || 'Elapsed:';

    console.log(currentName, '[' + this.getElapsedMilliseconds() + 'ms]', '[' + this.getElapsedSeconds() + 's]');
};

Benchmark

var stopwatch = new StopWatch();
stopwatch.start();

for (var index = 0; index < 100; index++) {
    stopwatch.printElapsed('Instance[' + index + ']');
}

stopwatch.stop();

stopwatch.printElapsed();

Output

Instance[0] [0ms] [0s]
Instance[1] [2.999999967869371ms] [0.002999999967869371s]
Instance[2] [2.999999967869371ms] [0.002999999967869371s]
/* ... */
Instance[99] [10.999999998603016ms] [0.010999999998603016s]
Elapsed: [10.999999998603016ms] [0.010999999998603016s]

performance.now() is optional - just pass false into StopWatch constructor function.

kayz1
  • 7,260
  • 3
  • 53
  • 56
10

To extend vsync's code further to have the ability to return the timeEnd as a value in NodeJS use this little piece of code.

console.timeEndValue = function(label) { // Add console.timeEndValue, to add a return value
   var time = this._times[label];
   if (!time) {
     throw new Error('No such label: ' + label);
   }
   var duration = Date.now() - time;
   return duration;
};

Now use the code like so:

console.time('someFunction timer');

someFunction();

var executionTime = console.timeEndValue('someFunction timer');
console.log("The execution time is " + executionTime);


This gives you more possibilities. You can store the execution time to be used for more purposes like using it in equations, or stored in a database, sent to a remote client over websockets, served on a webpage, etc.

Levi Roberts
  • 1,277
  • 3
  • 22
  • 44
10

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.

0x6A75616E
  • 4,696
  • 2
  • 33
  • 57
Rohit Jaiswal
  • 257
  • 4
  • 6
7

This is a Timer function. If you want to measure the time between multiple things that aren't nested:

function timer(lap){ 
    if(lap) console.log(`${lap} in: ${(performance.now()-timer.prev).toFixed(3)}ms`); 
    timer.prev = performance.now();
}

Similar to console.time(), but easier usage if you don't need to keep track of previous timers.


Usage:

timer()              // set the start
// do something 
timer('built')       // logs 'built in: 591.815ms'
// do something
timer('copied')      // logs 'copied in: 0.065ms'
// do something
timer('compared')    // logs 'compared in: 36.41ms'

If you like the blue color from console.time(), you can use this line instead

console.log(`${lap} in: %c${(performance.now()-timer.prev).toFixed(3)}ms`, 'color:blue');
aljgom
  • 7,879
  • 3
  • 33
  • 28
7

It may help you.

var t0 = date.now(); doSomething(); var t1 = date.now(); console.log("Call to doSomething took approximate" + (t1 - t0)/1000 + " seconds.")

Wajeeh Aslam
  • 71
  • 1
  • 2
  • 3
    While this code snippet may solve the question, [including an explanation](//meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. Please also try not to crowd your code with explanatory comments, this reduces the readability of both the code and the explanations! – Filnor Mar 16 '18 at 07:09
6

Since console.time and performance.now aren't supported in some major browsers (i.e. IE10), I created a slim utility that utilizes the best available methods. However, it lacks error handling for false usages (calling End() on a not initialized timer).

Use it and improve it as you want.

Performance: {
    Timer: {},
    Start: function (name) {
        if (console && console.time) {
            console.time(name);
        } else if (window.performance.now) {
            this.Timer[name] = window.performance.now();
        } else {
            this.Timer[name] = new Date().getTime();
        }
    },
    End: function (name) {
        if (console && console.time) {
            console.timeEnd(name);
        } else {
            var result;
            if (window.performance.now) {
                result = window.performance.now() - this.Timer[name];
            } else {
                result = new Date().getTime() - this.Timer[name];
            }
            console.log(name + ": " + result);
        }
    }
}
Karthikeyan
  • 990
  • 5
  • 12
Mx.
  • 3,588
  • 2
  • 25
  • 33
6

Use this code format

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

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

A couple months ago I put together my own routine that times a function using Date.now() -- even though at the time the accepted method seemed to be performance.now() -- because the performance object is not yet available (built-in) in the stable Node.js release.

Today I was doing some more research and found another method for timing. Since I also found how to use this in Node.js code, I thought I would share it here.

The following is combined from the examples given by w3c and Node.js:

function functionTimer() {
    performance.mark('start')
    functionToBeTimed()
    performance.mark('end')
    performance.measure('Start to End', 'start', 'end')
    const measure = performance.getEntriesByName('Start to End')[0]
    console.log(measure.duration)
}

NOTE:

If you intend to use the performance object in a Node.js app, you must include the following require: const { performance } = require('perf_hooks')

4

Thanks, Achim Koellner, will expand your answer a bit:

var t0 = process.hrtime();
//Start of code to measure

//End of code
var timeInMilliseconds = process.hrtime(t0)[1]/1000000; // dividing by 1000000 gives milliseconds from nanoseconds

Please, note, that you shouldn't do anything apart from what you want to measure (for example, console.log will also take time to execute and will affect performance tests).

Note, that in order by measure asynchronous functions execution time, you should insert var timeInMilliseconds = process.hrtime(t0)[1]/1000000; inside the callback. For example,

var t0 = process.hrtime();
someAsyncFunction(function(err, results) {
var timeInMilliseconds = process.hrtime(t0)[1]/1000000;

});
Andrew Marin
  • 1,053
  • 1
  • 13
  • 15
3

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');
iCPSoni
  • 101
  • 6
3

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.

Mario Varchmin
  • 3,704
  • 4
  • 18
  • 33
aryan singh
  • 374
  • 2
  • 9
2

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];
    }
};
gombosg
  • 893
  • 10
  • 11
2

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

toonday
  • 501
  • 4
  • 13
1
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

jose920405
  • 7,982
  • 6
  • 45
  • 71
1

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"
    ]
 }
Yu Huang
  • 3,085
  • 2
  • 24
  • 22
1
  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).

bvdb
  • 22,839
  • 10
  • 110
  • 123
1

Note: Simplest implementation of pure functional, ES6 method, no extra variables needed, just 3 lines of codes. Handles sync and async codes, so no external libraries needed, works in both JavaScript and Node JS, can even use to test the latency of your APIs

// Create one-liner timer function
let [timer, timingMonitor] = [0, () => timer = !timer ? Date.now() : `${Date.now() - timer}ms`]
        
// Initiate timer
timingMonitor();
        
// Your code here
doSomething();
        
// End timer 
console.log(timingMonitor());

// Console output: "102ms", for example 
0

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'))
User_coder
  • 477
  • 1
  • 7
  • 21
-3

As previously stated check for and use built in timer. But if you want or need to write your own here is my two cents:

//=-=|Source|=-=//
/**
 * JavaScript Timer Object
 *
 *      var now=timer['elapsed'](); 
 *      timer['stop']();
 *      timer['start']();
 *      timer['reset']();
 * 
 * @expose
 * @method timer
 * @return {number}
 */
timer=function(){
    var a=Date.now();
    b=0;
    return{
        /** @expose */
        elapsed:function(){return b=Date.now()-a},
        start:function(){return a=Date.now()},
        stop:function(){return Date.now()},
        reset:function(){return a=0}
    }
}();

//=-=|Google Advanced Optimized|=-=//
timer=function(){var a=Date.now();b=0;return{a:function(){return b=Date.now()-a},start:function(){return a=Date.now()},stop:function(){return Date.now()},reset:function(){return a=0}}}();

Compilation was a success!

  • Original Size: 219 bytes gzipped (405 bytes uncompressed)
  • Compiled Size: 109 bytes gzipped (187 bytes uncompressed)
  • Saved 50.23% off the gzipped size (53.83% without gzip
NlaakALD
  • 377
  • 2
  • 6
  • 16
-7

The accepted answer is wrong !

Since JavaScript is asynchronous, the values of the variable end of the accepted answer would be wrong.

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

for (i = 0; i < 50000; ++i) {
// JavaScript is not waiting until the for is finished !!
}

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

The execution of the for may be very fast so you can not see that the result is wrong. You can test it with a code doing some request :

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

for (i = 0; i < 50000; ++i) {
  $.ajax({
    url: 'www.oneOfYourWebsites.com',
    success: function(){
       console.log("success");
    }
  });
}

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

So the alert will prompt very quickly but in the console you'll see that the ajax requests are continuing.

Here is how you should do it : https://developer.mozilla.org/en-US/docs/Web/API/Performance.now

Mirza Selimovic
  • 1,669
  • 15
  • 18
  • 10
    It's not because of the for loop. A for loop will wait until the last loop until it will go on down your sourcecode. AJAX calls are async. And there are also other functions that run async. But a for loop is not executet async. – Scriptlabs Mar 12 '15 at 19:21