24

How can I measure the execution time of a npm/yarn task on the command line without modifying the scripts.

In my special use case I want to execute an existing E2E-Test (yarn test:e2e) 100 times and take the average value.

Andrea Carraro
  • 9,731
  • 5
  • 33
  • 57

4 Answers4

45

You could use the npm package gnomon:

A command line utility, a bit like moreutils's ts, to prepend timestamp information to the standard output of another command.

Install it like this:

$ npm i -g gnomon

With this you could run:

$ yarn install | gnomon

And it might give you an output like this:

$ yarn install | gnomon 
   0.5327s   yarn install v1.9.4
   1.9652s   [1/4] Resolving packages...
   0.0160s   success Already up-to-date.
   0.0163s   Done in 2.38s.
   0.0003s   

     Total   2.5315s
Andresch Serj
  • 35,217
  • 15
  • 59
  • 101
  • What does `|` means? – wonsuc Dec 31 '20 at 01:05
  • `|` is Unix' pipe operator, details here: https://en.wikipedia.org/wiki/Pipeline_(Unix) –  Jan 15 '21 at 08:28
  • This does not work for me (on windows). It prints the time for some of the tasks (which are really fast) and claims the total time is less than a second. But then there are other tasks that take much longer which are not shown at all. (The overall script takes almost 2 minutes) – Zaphoid Jul 26 '22 at 12:46
  • sorry, I use linux/unix/mac only, no idea about windows –  Aug 12 '22 at 10:06
  • 3
    Note: even though this is up-voted, it doesn't seem to work anymore, or work with `pnpm`. The repo has been archived. – Matthew Dean Nov 20 '22 at 20:36
  • It's not working, it's showing 0.006s in my project where I have 100s of packages – Mr.7 Jan 28 '23 at 06:26
38

Use the following command in unix

time npm run build

For windows use this command

Measure-Command { start-process npm 'run build' -wait}
rbansal
  • 1,184
  • 14
  • 21
  • Note: powershell-specific, which means that anyone who uses `cmd` for maximum cross-platform compatibility still doesn't have a solution (`cmd` supports `&&`, for example. Kind of essential in the world of node scripts) – Mike 'Pomax' Kamermans Mar 26 '21 at 23:04
  • Nice trick! :) I guess it only works in PowerShell. Of course you only get the total timing (and you don't see the script output as it's run in a separate shell). But still good for basic tests! – Zaphoid Jul 26 '22 at 12:47
  • If you want to see output include a pipe to write-host and also you can run the command in current scope. ``` Measure-Command { npm 'run build' | write-host } ``` – Zohar Chiprut Oct 11 '22 at 10:37
2

If you don't want any global or even local dependencies for this, or you don't want something that only works on unixy operating systems, this is almost trivially achieved with a simple .js file and an equally simple npm script refinement:

{
  ...
  "scripts: {
    "time": "node mark.js",
    "start": "npm run time && ...whatever 'start' was before... && npm run time",
  },
  ...
}

With that mark.js file being the almost trivial following code:

const fs = require("fs"); // or import fs from "fs"; if you're working on modern JS

const timingFile = `.timing`;

if(fs.existsSync(timingFile)) {
  const end = Date.now();
  const start = fs.readFileSync(timingFile);
  fs.unlinkSync(timingFile);
  console.log(`Runtime: ${(end - start)/1000}s`);
} else { fs.writeFileSync(timingFile, `${Date.now()}`, `utf8`); }
Mike 'Pomax' Kamermans
  • 49,297
  • 16
  • 112
  • 153
0

Inspired by @user1816491 answer, I remembered that I used to use a shell utility, ts.

In unix (apt is for debian/ubuntu), install moreutils that contains ts, as e.g.

sudo apt install moreutils -y

Then e.g.

$ npm run build | ts '%FT%T'
2022-08-24T09:55:13 
2022-08-24T09:55:13 > build
2022-08-24T09:55:13 > next build
2022-08-24T09:55:13

or

$ npm run build | ts -s '[%H:%M:%.S]'
[00:00:00.416378] 
[00:00:00.416511] > build
[00:00:00.416577] > next build
[00:00:00.416603]