Friday, May 1, 2015

Measure windows cmd.exe command execution time

The *nix command 'time' is very useful for timing how long commands take. To do the same with the windows command line you have two options. The best is to use powershell's 'Measure-Command', in this case measuring 2 seconds of sleep:
C:\>powershell "Measure-Command{sleep 2}"


Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 1
Milliseconds      : 992
Ticks             : 19924681
TotalDays         : 2.30609733796296E-05
TotalHours        : 0.000553463361111111
TotalMinutes      : 0.0332078016666667
TotalSeconds      : 1.9924681
TotalMilliseconds : 1992.4681
By default Measure-Command will suppress stdout:
C:\Users\vagrant>powershell "Measure-Command{ps}"


Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 0
Milliseconds      : 78
Ticks             : 781767
TotalDays         : 9.04822916666667E-07
TotalHours        : 2.171575E-05
TotalMinutes      : 0.001302945
TotalSeconds      : 0.0781767
TotalMilliseconds : 78.1767
If you want to see it you can just pipe it to Out-Default:
C:\>powershell "Measure-Command{ps | Out-Default}"

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
     23       5     3272       3540    46     0.06   3056 cmd

[snip]

    221      15     4388       3620    95     0.09   2496 wmpnetwk

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 0
Milliseconds      : 309
Ticks             : 3097644
TotalDays         : 3.58523611111111E-06
TotalHours        : 8.60456666666667E-05
TotalMinutes      : 0.00516274
TotalSeconds      : 0.3097644
TotalMilliseconds : 309.7644
Or if you want to time a bat file:
C:\>powershell "Measure-Command{& C:\mybatfile.bat | Out-Default}"
There is another way to time commands using the %TIME% environment variable. However there is a gotcha, this example doesn't work because the environment variables are evaluated at the same time when the command is executed:
::This is broken
C:\>echo %TIME% && sleep 2 && echo %TIME%
10:47:36.10
10:47:36.10
You can work around this by running up a new cmd.exe with /v:on which enables delayed environment variable expansion when you specify them with "!". The downside to this approach is that you need to do the maths yourself, and you may need to redirect the output of your target command or your echo statements to a file to avoid the first one disappearing off the screen if there is lots of output.
C:\>cmd /v:on /c "echo !TIME! && sleep 2 && echo !TIME!"
10:42:15.71
10:42:17.73