Is there a built-in way to measure execution time of a command on the Windows command line?
34 Answers
PowerShell has a cmdlet for this called Measure-Command
. You'll have to ensure that PowerShell is available on the machine that runs it.
PS> Measure-Command { echo hi }
Days : 0
Hours : 0
Minutes : 0
Seconds : 0
Milliseconds : 0
Ticks : 1318
TotalDays : 1.52546296296296E-09
TotalHours : 3.66111111111111E-08
TotalMinutes : 2.19666666666667E-06
TotalSeconds : 0.0001318
TotalMilliseconds : 0.1318
Measure-Command
captures the command's output. You can redirect the output back to your console using Out-Default
:
PS> Measure-Command { echo hi | Out-Default }
hi
Days : 0
...
As Makotoe commented, Measure-Command
returns a TimeSpan
object, so the measured time is printed as a bunch of fields. You can format the object into a timestamp string using ToString()
:
PS> (Measure-Command { echo hi | Out-Default }).ToString()
hi
00:00:00.0001318
If the command inside Measure-Command
changes your console text color, use [Console]::ResetColor()
to reset it back to normal.
-
23This is the best solution for Windows 7 users as timeit.exe doesn't appear to support Windows 7 Oct 25, 2011 at 0:08
-
16In case you want to use internal dos commands (eg.: dir, echo, del, etc.) don't forget to insert "cmd /c": Measure-Command { cmd /c dir /s c:\windows > nul } Jan 10, 2012 at 10:49
-
13If you're benchmarking an
.exe
in the current directory, use this:Measure-Command { .\your.exe }
. PowerShell apparently doesn't run things frompwd
unless explicitly told to. Sep 10, 2013 at 15:02 -
3Use this
powershell -Command Measure-Command { YOUR_COMMAND }
this does not hide thestdout
. Aug 19, 2016 at 11:34 -
6Ray pixar misquoted vladimir. It should be
Measure-Command { YOUR_COMMAND | Out-Default}
Jul 27, 2017 at 17:41
If you want
- To measure execution time down to the hundredth of a second in (hh:mm:ss.ff format)
- To not have to download and install a resource pack
- To look like a huge DOS nerd (who doesn't)
Try copying the following script into a new batch file (e.g. timecmd.bat):
@echo off
@setlocal
set start=%time%
:: Runs your command
cmd /c %*
set end=%time%
set options="tokens=1-4 delims=:.,"
for /f %options% %%a in ("%start%") do set start_h=%%a&set /a start_m=100%%b %% 100&set /a start_s=100%%c %% 100&set /a start_ms=100%%d %% 100
for /f %options% %%a in ("%end%") do set end_h=%%a&set /a end_m=100%%b %% 100&set /a end_s=100%%c %% 100&set /a end_ms=100%%d %% 100
set /a hours=%end_h%-%start_h%
set /a mins=%end_m%-%start_m%
set /a secs=%end_s%-%start_s%
set /a ms=%end_ms%-%start_ms%
if %ms% lss 0 set /a secs = %secs% - 1 & set /a ms = 100%ms%
if %secs% lss 0 set /a mins = %mins% - 1 & set /a secs = 60%secs%
if %mins% lss 0 set /a hours = %hours% - 1 & set /a mins = 60%mins%
if %hours% lss 0 set /a hours = 24%hours%
if 1%ms% lss 100 set ms=0%ms%
:: Mission accomplished
set /a totalsecs = %hours%*3600 + %mins%*60 + %secs%
echo command took %hours%:%mins%:%secs%.%ms% (%totalsecs%.%ms%s total)
Usage
If you put timecmd.bat in a directory in your path, you can call it from anywhere like this:
timecmd [your command]
E.g.
C:\>timecmd pause
Press any key to continue . . .
command took 0:0:1.18
If you want to do output redirection, you can quote the command like this:
timecmd "dir c:\windows /s > nul"
This should handle commands that run from before- to after-midnight, but the output will be wrong if your command runs for 24 hours or more.
-
11replacing cmd /c %* with %* works unless your command is another batch file. Then you'd have to do timecmd call other.bat Mar 27, 2013 at 16:50
-
4For some reason this only gives me output in whole seconds... which for me is useless. I mean that I run
timecmd pause
, and it always results in 1.00 sec, 2.00 sec, 4.00 sec... even 0.00 sec! Windows 7. Sep 25, 2013 at 16:00 -
10@CamiloMartin & others who had this (like me) - you may have a locale, which uses COMMA instead of DOT for decimal. So, in this scrpit, change
delims=:.
todelims=:.,
, and then it should work "across the board". Sep 11, 2014 at 11:19 -
5There's a serious arithmetic error in that script: Try it with:
set start=10:10:10.10
set end=10:11:10.09
And it'll output:command took 0:1:-1.99 (59.99s total)
You should reverse the order of the 4 lines that do "lss 0" comparisons, so that the carry progresses correctly from low to high sexagesimal digits. Then the output becomes:command took 0:0:59.99 (59.99s total)
Dec 2, 2014 at 16:04 -
3For anyone wondering: the fixes by TomaszGandor and Jean-FrançoisLarvoire have been edited into the script above. Also @Jashan: there's a buggy bug in your milliseconds padding (it's actually hundredths, and you're using the
secs
var instead ofms
), so it should be:set "ms=0%ms%"
andset "ms=%ms:~-2%"
. But other than that, I like this!– PaulJun 23, 2019 at 18:01
Hehe, the most simple solution might be this:
echo %time%
YourApp.exe
echo %time%
This works on every Windows out of the box.
In case of an application using console output, it might be convenient to store the starting time in a temporary variable:
set startTime=%time%
YourApp.exe
echo Start Time: %startTime%
echo Finish Time: %time%
-
2
-
13Even better (if your app spits output to the console):
set startTime=%time% \n YourApp.exe \n echo Start Time: %startTime% \n echo Finish Time: %time%
(Sorry, couldn't get newlines in the comment)– JonoJun 3, 2012 at 15:52 -
5No, this is a bad option. This tells you the wall-clock time, not the CPU time. So, even though your command line might take only 100ms, if there's another application hogging the CPU, your application may take seconds (off by 100x or more). In fact, if your machine is thrashing, you could even wait a minute for your little 100ms app to run. Track CPU time, not wall clock time! Oct 20, 2014 at 16:32
-
2@MykhayloKopytonenko Yes it can:
echo %time% && YourCmd --with -- -params && echo %time%
– DaJunkieMay 3, 2018 at 10:10 -
2I know that my answer does not compute the execution time. However please take into consideration that when I wrote the answer in March 2010, the most common Windows operating system was Windows XP/Server 2003, which didn't have PowerShell installed by default. The above solution worked out of the box, without installing additional software (which is especially helpful in a corporate environment). Aug 17, 2020 at 10:11
Just a little expansion of the answer from Casey.K about using the Measure-Command
from PowerShell:
You can invoke PowerShell from the standard command prompt, like this:
powershell -Command "Measure-Command {echo hi}"
This will eat the standard output, but you can prevent that by adding
| Out-Default
like this from PowerShell:Measure-Command {echo hi | Out-Default}
Or from a command prompt:
powershell -Command "Measure-Command {echo hi | Out-Default}"
Of course, you're free to wrap this in a script file *.ps1
or *.bat
.
-
2What if the command we want to measure has quotes? Can can this be turned into a .bat script in that case? For example
measureTime.bat "c:\program files\some dir\program.exe"
– GetFreeSep 10, 2018 at 22:31
If you are using Windows 2003 (note that windows server 2008 and later are not supported) you can use The Windows Server 2003 Resource Kit, which contains timeit.exe that displays detailed execution stats. Here is an example, timing the command "timeit -?":
C:\>timeit timeit -?
Invalid switch -?
Usage: TIMEIT [-f filename] [-a] [-c] [-i] [-d] [-s] [-t] [-k keyname | -r keyname] [-m mask] [commandline...]
where: -f specifies the name of the database file where TIMEIT
keeps a history of previous timings. Default is .\timeit.dat
-k specifies the keyname to use for this timing run
-r specifies the keyname to remove from the database. If
keyname is followed by a comma and a number then it will
remove the slowest (positive number) or fastest (negative)
times for that keyname.
-a specifies that timeit should display average of all timings
for the specified key.
-i specifies to ignore non-zero return codes from program
-d specifies to show detail for average
-s specifies to suppress system wide counters
-t specifies to tabular output
-c specifies to force a resort of the data base
-m specifies the processor affinity mask
Version Number: Windows NT 5.2 (Build 3790)
Exit Time: 7:38 am, Wednesday, April 15 2009
Elapsed Time: 0:00:00.000
Process Time: 0:00:00.015
System Calls: 731
Context Switches: 299
Page Faults: 515
Bytes Read: 0
Bytes Written: 0
Bytes Other: 298
You can get TimeIt in the Windows 2003 Resource Kit. It's not available for direct download from the Microsoft Download Center, but one can still get it from the archive.org - Windows Server 2003 Resource Kit Tools.
-
8This kit has issues with windows 2008 64bit and does not work on 2008 R2– ArtemNov 12, 2009 at 2:29
-
is there any way to also measure kernel time and/or the time used by spawned sub processes? Feb 21, 2011 at 22:55
-
43FYI - I don't think timeit works on Windows 7 64-bit. You get the error "Unable to query system performance data (c0000004). Instead, use PowerShell's "Measure-Command" like Casey.K suggests: stackoverflow.com/questions/673523/… Oct 25, 2011 at 0:05
-
7In Windows 7 I see "'timeit' is not recognized as an internal or external command, operable program or batch file." Sep 12, 2013 at 15:11
-
5I don't see the command in Windows 10, nor do I easily find a Resource Kit for Win 10. Does anyone know how to get this for 10? Jan 25, 2018 at 14:35
The one-liner I use in Windows Server 2008 R2 is:
cmd /v:on /c "echo !TIME! & *mycommand* & echo !TIME!"
So long as mycommand doesn't require quotes (which screws with cmd's quote processing). The /v:on
is to allow for the two different TIME values to be evaluated independently rather than once at the execution of the command.
-
This also won't work for the "spam" batches, which overwrite the first time label and implies that you replace the computer doing the computation, as noted in stackoverflow.com/questions/673523/…– ValJul 11, 2013 at 18:01
-
-
2If you repeat the cmd /v:on for the second timing, we can even have mycommand contain quotes. Example:
cmd /v:on /c echo !TIME! & echo "Quoted mycommand" & cmd /v:on /c echo !TIME!
. Feb 19, 2015 at 9:35 -
11Simpler:
echo %time% & *mycommand* & call echo %^time%
. See also this answer.– AaciniMar 7, 2017 at 2:39 -
If your command outputs too much, maybe it's easier just put the 2 time together:
cmd /v:on /c "mycommand & echo begin=%time% endtime=!time!"
Feb 11, 2020 at 2:03
If you have a command window open and call the commands manually, you can display a timestamp on each prompt, e.g.
prompt $d $t $_$P$G
It gives you something like:
23.03.2009 15:45:50,77
C:\>
If you have a small batch script that executes your commands, have an empty line before each command, e.g.
(empty line)
myCommand.exe
(next empty line)
myCommand2.exe
You can calculate the execution time for each command by the time information in the prompt. The best would probably be to pipe the output to a textfile for further analysis:
MyBatchFile.bat > output.txt
-
2Simple, elegant, no install and no writing a batch files for a one shot command and can time every step in a batch file.– MattApr 16, 2019 at 8:56
Since others are recommending installing things like freeware and PowerShell, you could also install Cygwin, which would give you access to many basic Unix commands like time:
abe@abe-PC:~$ time sleep 5
real 0m5.012s
user 0m0.000s
sys 0m0.000s
Not sure how much overhead Cygwin adds.
-
I have also upvoted this since I found it the easiest solution since the free program Cmder includes bash! cmder.net Just remember that if you need to escape spaces in bash, use a blackslash \ just before the space, instead of "quotes". eg, cd /c/Program\ Files/ Jun 1, 2017 at 15:52
-
I am the developer and use WSL. %windir%\system32\wsl.exe -cur_console:pm:/mnt And we have a bash command-line :-)– QuazerOct 15, 2021 at 11:24
-
can OP provide an example in
CMD
script of how to implement this to measure the duration of that script....within the script preferably.– Jon GrahAug 16, 2022 at 5:00
Not quite as elegant as some of the functionality on Unix, but create a cmd file which looks like:
@echo off
time < nul
yourexecutable.exe > c:\temp\output.txt
time < nul
rem on newer windows system you can try time /T
That will display the start and stop times like so:
The current time is: 10:31:57.92
Enter the new time:
The current time is: 10:32:05.94
Enter the new time:
-
2Assuming you don't need portability across different languages you can also put a findstr "current" or something like that after the "time < nul" (nice usage of nul by the way; I've always used echo.|time, but that doesn't look as elegant :)). And use "for" to extract only the time, not the text.– JoeyMar 23, 2009 at 18:24
-
2If command extensions are enabled (that is, the default), the Win XP version of
time
has a/t
option which just displays the current system time, without prompting you to enter a new time. However when you do that it only displays hours and minutes, which might not be good enough for some usages. (See John Snow's answer to this question.) Jan 23, 2011 at 18:34 -
3
time /T
is usable only if the process runs for several minutes!time < nul
is uglier but more precise.– PhiLhoJun 4, 2013 at 10:59 -
7You could also use
echo %time%
which provides the same format and precision astime < nul
, but you avoid theEnter the new time:
output...– aschipflSep 1, 2015 at 23:55 -
for locale-independent amd more precise time use
wmic os get LocalDateTime
– phuclvJul 11, 2017 at 2:34
I use freeware called "GS Timer".
Just make a batch file like this:
timer
yourapp.exe
timer /s
If you need a set of times, just pipe the output of timer /s into a .txt file.
You can get it here: Gammadyne's Free DOS Utilities
The resolution is 0.1 seconds.
-
4I don't think using a third party application could be considered doing it "with standard means". Jan 23, 2011 at 18:37
-
5The questioner meant "without installing additional software", but then the top (accepted) answer also requires installing a whole Windows 2003 Resource Kit! Anyway, timer.exe was perfect for what I was just looking for, thanks!– HugoMay 27, 2011 at 10:32
-
I'm using Windows XP and for some reason timeit.exe does not work for me. I found another alternative - PTIME. This works very well.
http://www.pc-tools.net/win32/ptime/
Example -
C:\> ptime
ptime 1.0 for Win32, Freeware - http://www.pc-tools.net/
Copyright(C) 2002, Jem Berkes <[email protected]>
Syntax: ptime command [arguments ...]
ptime will run the specified command and measure the execution time
(run time) in seconds, accurate to 5 millisecond or better. It is an
automatic process timer, or program timer.
C:\> ptime cd
ptime 1.0 for Win32, Freeware - http://www.pc-tools.net/
Copyright(C) 2002, Jem Berkes <[email protected]>
=== cd ===
C:\
Execution time: 0.015 s
-
Works well on Windows 8.1 also. I renamed mine to timer.exe, because I can never remember the name ptime. Aug 9, 2015 at 16:50
As long as it doesn't last longer than 24hours...
@echo off
set starttime=%TIME%
set startcsec=%STARTTIME:~9,2%
set startsecs=%STARTTIME:~6,2%
set startmins=%STARTTIME:~3,2%
set starthour=%STARTTIME:~0,2%
set /a starttime=(%starthour%*60*60*100)+(%startmins%*60*100)+(%startsecs%*100)+(%startcsec%)
:TimeThis
ping localhost
set endtime=%time%
set endcsec=%endTIME:~9,2%
set endsecs=%endTIME:~6,2%
set endmins=%endTIME:~3,2%
set endhour=%endTIME:~0,2%
if %endhour% LSS %starthour% set /a endhour+=24
set /a endtime=(%endhour%*60*60*100)+(%endmins%*60*100)+(%endsecs%*100)+(%endcsec%)
set /a timetaken= ( %endtime% - %starttime% )
set /a timetakens= %timetaken% / 100
set timetaken=%timetakens%.%timetaken:~-2%
echo.
echo Took: %timetaken% sec.
-
5Impressive, but I don't think it works if there's an 08 or 09 in the start or end times because these are interpreted as octals. My answer handles that :)– user87453Jun 2, 2011 at 1:26
There's also TimeMem (March 2012):
This is a Windows utility which executes a program and displays its execution time, memory usage, and IO statistics. It is similar in functionality to the Unix time utility.
Depending on the version of Windows you're using, just running bash
will put you into Bash mode. This will allow you to use a bunch of commands that are not available on PowerShell directly (like the time
command). Timing your command is now as easy as executing:
# The clause <your-command> (without the angle brackets) denotes the command you want to run.
$ time <your-command>
Note: You can easily quit from Bash mode and return back into your mainstream shell by running
exit
while in Bash mode.
This worked for me perfectly (Windows 10) after trying out other methods (like Measure-Command
) which sometimes produce undesired stats. Hope this works for you as well.
-
4
Here is a
Postfix timer version:
Usage example:
timeout 1 | TimeIt.cmd
Execution took ~969 milliseconds.
Copy & paste this into some editor like for example Notepad++ and save it as TimeIt.cmd:
:: --- TimeIt.cmd ----
@echo off
setlocal enabledelayedexpansion
call :ShowHelp
:: Set pipeline initialization time
set t1=%time%
:: Wait for stdin
more
:: Set time at which stdin was ready
set t2=!time!
:: Calculate difference
Call :GetMSeconds Tms1 t1
Call :GetMSeconds Tms2 t2
set /a deltaMSecs=%Tms2%-%Tms1%
echo Execution took ~ %deltaMSecs% milliseconds.
endlocal
goto :eof
:GetMSeconds
Call :Parse TimeAsArgs %2
Call :CalcMSeconds %1 %TimeAsArgs%
goto :eof
:CalcMSeconds
set /a %1= (%2 * 3600*1000) + (%3 * 60*1000) + (%4 * 1000) + (%5)
goto :eof
:Parse
:: Mask time like " 0:23:29,12"
set %1=!%2: 0=0!
:: Replace time separators with " "
set %1=!%1::= !
set %1=!%1:.= !
set %1=!%1:,= !
:: Delete leading zero - so it'll not parsed as octal later
set %1=!%1: 0= !
goto :eof
:ShowHelp
echo %~n0 V1.0 [Dez 2015]
echo.
echo Usage: ^<Command^> ^| %~nx0
echo.
echo Wait for pipe getting ready... :)
echo (Press Ctrl+Z ^<Enter^> to Cancel)
goto :eof
^ - Based on 'Daniel Sparks' Version
An alternative to measure-time is simply "Get-Date". You don't have that hassle with forwarding output and so on.
$start = Get-Date
[System.Threading.Thread]::Sleep(1500)
$(Get-Date) - $start
Output:
Days : 0
Hours : 0
Minutes : 0
Seconds : 1
Milliseconds : 506
Ticks : 15060003
TotalDays : 1.74305590277778E-05
TotalHours : 0.000418333416666667
TotalMinutes : 0.025100005
TotalSeconds : 1.5060003
TotalMilliseconds : 1506.0003
-
Get-Date command works all right in PowerShell, unfortunately it does not in regular command prompt on Windows 10.– Ionut V.Oct 2, 2020 at 7:57
-
To be accurate, you'd want to run all 3 commands back-to-back.
$start = Get-Date ; "slow command here" ; ($(Get-Date) - $start)
– MarkHuAug 30, 2023 at 22:14
This is a one-liner which avoids delayed expansion, which could disturb certain commands:
cmd /E /C "prompt $T$$ & echo.%TIME%$ & COMMAND_TO_MEASURE & for %Z in (.) do rem/ "
The output is something like:
14:30:27.58$ ... 14:32:43.17$ rem/
For long-term tests replace $T
by $D, $T
and %TIME%
by %DATE%, %TIME%
to include the date.
To use this inside of a batch file, replace %Z
by %%Z
.
Update
Here is an improved one-liner (without delayed expansion too):
cmd /E /C "prompt $D, $T$$ & (for %# in (.) do rem/ ) & COMMAND_TO_MEASURE & for %# in (.) do prompt"
The output looks similar to this:
2015/09/01, 14:30:27.58$ rem/ ... 2015/09/01, 14:32:43.17$ prompt
This approach does not include the process of instancing a new cmd
in the result, nor does it include the prompt
command(s).
If you have CMake installed, you can just run following command.
cmake -E time <the_command_to_measure_run_time>
Here is my method, no conversion and no ms. It is useful to determine encoding durations (limited to 24 hours though):
@echo off
:start
REM Start time storage
set ST=%time%
echo Process started at %ST%
echo.
echo.
REM Your commands
REM Your commands
REM Your commands
:end
REM Start Time Definition
for /f "tokens=1-3 delims=:" %%a in ("%ST%") do set /a h1=%%a & set /a m1=%%b & set /a s1=%%c
REM End Time Definition
for /f "tokens=1-3 delims=:" %%a in ("%TIME%") do set /a h2=%%a & set /a m2=%%b & set /a s2=%%c
REM Difference
set /a h3=%h2%-%h1% & set /a m3=%m2%-%m1% & set /a s3=%s2%-%s1%
REM Time Adjustment
if %h3% LSS 0 set /a h3=%h3%+24
if %m3% LSS 0 set /a m3=%m3%+60 & set /a h3=%h3%-1
if %s3% LSS 0 set /a s3=%s3%+60 & set /a m3=%m3%-1
echo Start : %ST%
echo End : %time%
echo.
echo Total : %h3%:%m3%:%s3%
echo.
pause
In case anyone else has come here looking for an answer to this question, there's a Windows API function called GetProcessTimes()
. It doesn't look like too much work to write a little C program that would start the command, make this call, and return the process times.
-
4It doesn't look like too much work to download a little C program that would start the command, make this call (and much more advance measurements), and return the process times. Sep 28, 2011 at 7:24
-
-
@KeyWeeUsr you can use Windows API IIRC from PS blogs.technet.microsoft.com/heyscriptingguy/2013/06/25/… Apr 11, 2017 at 18:48
-
In the directory where your program is, type
notepad mytimer.bat
, click 'yes' to create a new file.Paste the code below, replacing
YourApp.exe
with your program, then save.@echo off date /t time /t YourApp.exe date /t time /t
Type
mytimer.bat
in the command line then press Enter.
-
7time /t only gives you time in HH:MM. To time an executable, you usually needs more accuracy... Is it anything you can setup to get down to fractions of a second? I tested the sollution from JohnW (time < nul), and that actually gives the time down to 1/100s: HH:MM:SS.XX– aweAug 17, 2009 at 6:03
my code gives you the running time in milliseconds, up to 24 hrs, it is locale insensitive, and accounts for negative values if code runs through midnight. it uses delayed expansion, and should be saved in a cmd/bat file.
before your code:
SETLOCAL EnableDelayedExpansion
for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set t=%%I
set /a t1 = %t:~8,1%*36000 + %t:~9,1%*3600 + %t:~10,1%*600 + %t:~11,1%*60 + %t:~12,1%*10 + %t:~13,1% && set t1=!t1!%t:~15,3%
after your code:
for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set t=%%I
set /a t2 = %t:~8,1%*36000 + %t:~9,1%*3600 + %t:~10,1%*600 + %t:~11,1%*60 + %t:~12,1%*10 + %t:~13,1% && set t2=!t2!%t:~15,3%
set /a t2-=t1 && if !t2! lss 0 set /a t2+=24*3600000
if you want running time in HH:mm:ss.000 format, add:
set /a "h=t2/3600000,t2%%=3600000,m=t2/60000,t2%%=60000" && set t2=00000!t2!&& set t2=!t2:~-5!
if %h% leq 9 (set h=0%h%) && if %m% leq 9 (set m=0%m%)
set t2=%h%:%m%:%t2:~0,2%.%t2:~2,3%
ENDLOCAL
variable t2
holds your running time, you can echo %t2%
to display it.
This is a comment/edit to Luke Sampson's nice timecmd.bat
and reply to
For some reason this only gives me output in whole seconds... which for me is useless. I mean that I run timecmd pause, and it always results in 1.00 sec, 2.00 sec, 4.00 sec... even 0.00 sec! Windows 7. – Camilo Martin Sep 25 '13 at 16:00 "
On some configurations the delimiters may differ. The following change should cover atleast most western countries.
set options="tokens=1-4 delims=:,." (added comma)
The %time%
milliseconds work on my system after adding that ','
(*because site doesn't allow anon comment and doesn't keep good track of identity even though I always use same guest email which combined with ipv6 ip and browser fingerprint should be enough to uniquely identify without password)
-
I commented just that before scrolling down to your answer. Anyway, Luke's script could zero-pad hours, minutes and seconds, not just the subseconds (which are centiseconds, and not milliseconds, BTW). See here: en.wiktionary.org/wiki/centisecond Sep 11, 2014 at 11:32
Another approach with powershell:
@echo off
for /f %%t in ('powershell "(get-date).tofiletime()"') do set mst=%%t
rem some commands
powershell ((get-date).tofiletime() - %mst%)
this will print the execution time in milliseconds.
@echo off & setlocal
set start=%time%
REM Do stuff to be timed here.
REM Alternatively, uncomment the line below to be able to
REM pass in the command to be timed when running this script.
REM cmd /c %*
set end=%time%
REM Calculate time taken in seconds, to the hundredth of a second.
REM Assumes start time and end time will be on the same day.
set options="tokens=1-4 delims=:."
for /f %options% %%a in ("%start%") do (
set /a start_s="(100%%a %% 100)*3600 + (100%%b %% 100)*60 + (100%%c %% 100)"
set /a start_hs=100%%d %% 100
)
for /f %options% %%a in ("%end%") do (
set /a end_s="(100%%a %% 100)*3600 + (100%%b %% 100)*60 + (100%%c %% 100)"
set /a end_hs=100%%d %% 100
)
set /a s=%end_s%-%start_s%
set /a hs=%end_hs%-%start_hs%
if %hs% lss 0 (
set /a s=%s%-1
set /a hs=100%hs%
)
if 1%hs% lss 100 set hs=0%hs%
echo.
echo Time taken: %s%.%hs% secs
echo.
-
Does not work. Getting: Unbalanced parenthesis. Unbalanced parenthesis. Missing operand. Dec 7, 2016 at 13:56
-
@RichardSandoz It works fine, there are no unbalanced parenthesis. How are you using it?– MikeMDec 7, 2016 at 15:14
The following script uses only "cmd.exe" and outputs the number of milliseconds from the time a pipeline is created to the time that the process preceding the script exits. i.e., Type your command, and pipe the to the script. Example: "timeout 3 | runtime.cmd" should yield something like "2990." If you need both the runtime output and the stdin output, redirect stdin before the pipe - ex: "dir /s 1>temp.txt | runtime.cmd" would dump the output of the "dir" command to "temp.txt" and would print the runtime to the console.
:: --- runtime.cmd ----
@echo off
setlocal enabledelayedexpansion
:: find target for recursive calls
if not "%1"=="" (
shift /1
goto :%1
exit /b
)
:: set pipeline initialization time
set t1=%time%
:: wait for stdin
more > nul
:: set time at which stdin was ready
set t2=!time!
::parse t1
set t1=!t1::= !
set t1=!t1:.= !
set t1=!t1: 0= !
:: parse t2
set t2=!t2::= !
set t2=!t2:.= !
set t2=!t2: 0= !
:: calc difference
pushd %~dp0
for /f %%i in ('%0 calc !t1!') do for /f %%j in ('%0 calc !t2!') do (
set /a t=%%j-%%i
echo !t!
)
popd
exit /b
goto :eof
:calc
set /a t=(%1*(3600*1000))+(%2*(60*1000))+(%3*1000)+(%4)
echo !t!
goto :eof
endlocal
-
-
Bug #1 Will fail at the 12'th hour. Example: " 0:23:19,42" Bug #2 Will fail if decimal point is anything else than . same example: " 0:23:19 , 42" here decimal point is , <__________> Well tried to edit however that dumb**** in the 'edit approval commission' rejected it - 3 of 5 voted "This edit changes too much of the authors original intent." so if feel like try your luck editing or just keep the bugs in - so the 'authors original intent stays intact'. facepalm– NaduDec 21, 2015 at 0:02
-
Can't output milliseconds when the resolution of your clock is barely capable of 1/100 second resolution. Nov 9, 2017 at 1:13
The answer of driblio can be made a little shorter (though not much readable)
@echo off
:: Calculate the start timestamp
set _time=%time%
set /a _hours=100%_time:~0,2%%%100,_min=100%_time:~3,2%%%100,_sec=100%_time:~6,2%%%100,_cs=%_time:~9,2%
set /a _started=_hours*60*60*100+_min*60*100+_sec*100+_cs
:: yourCommandHere
:: Calculate the difference in cSeconds
set _time=%time%
set /a _hours=100%_time:~0,2%%%100,_min=100%_time:~3,2%%%100,_sec=100%_time:~6,2%%%100,_cs=%_time:~9,2%
set /a _duration=_hours*60*60*100+_min*60*100+_sec*100+_cs-_started
:: Populate variables for rendering (100+ needed for padding)
set /a _hours=_duration/60/60/100,_min=100+_duration/60/100%%60,_sec=100+(_duration/100%%60%%60),_cs=100+_duration%%100
echo Done at: %_time% took : %_hours%:%_min:~-2%:%_sec:~-2%.%_cs:~-2%
::prints something like:
::Done at: 12:37:53,70 took: 0:02:03.55
To the remark of Luke Sampson this version is octal safe, though the task should be completed in 24 hours.
-
-
set _time=%time: =0%
fixes the single digit hour problem - replace in both places.– LaurJul 2, 2018 at 14:21
Having Perl installed the hires solution available, run:
C:\BATCH>time.pl "echo Fine result"
0.01063
Fine result
STDERR comes before measured seconds
#!/usr/bin/perl -w
use Time::HiRes qw();
my $T0 = [ Time::HiRes::gettimeofday ];
my $stdout = `@ARGV`;
my $time_elapsed = Time::HiRes::tv_interval( $T0 );
print $time_elapsed, "\n";
print $stdout;
A solution using pure PHP for cmd and one env. variable:
@echo off
setlocal enableextensions
REM set start time env var
FOR /F "tokens=* USEBACKQ" %%F IN (`php -r "echo microtime(true);"`) DO ( SET start_time=%%F )
## PUT_HERE_THE_COMMAND_TO_RUN ##
REM echo elapsed time
php -r "echo 'elapsed: ' . (round(microtime(true) - trim(getenv('start_time')), 2)) . ' seconds' . mb_convert_encoding(' ', 'UTF-8', 'HTML-ENTITIES');"
no need for cygwin or non-trusted utilities. Usefull when PHP is locally available
precision and output format can be easily tweaked
the same idea can be ported for PowerShell
None of the answers posted either worked well or were overly complicated to my taste, so here's what I saved as ptime.bat
@setlocal enableextensions disabledelayedexpansion
@echo off
if not [%1]==[] powershell -nol -noni -nop -c "measure-command { invoke-expression -command '%*' | write-host };"
still spazzes out if the first argument, i.e. the program to be executed, is a path containing spaces but I can live with that.