如何在Windows命令行中测量命令的执行时间?

是否有一种内置的方法来测量Windows命令行上命令的执行时间?

516384 次浏览

不像Unix上的一些功能那样优雅,但是创建一个cmd文件,看起来像这样:

@echo off
time < nul
yourexecutable.exe > c:\temp\output.txt
time < nul
rem on newer windows system you can try time /T

将显示开始和停止时间,如下所示:

The current time is: 10:31:57.92
Enter the new time:
The current time is: 10:32:05.94
Enter the new time:

如果你打开了一个命令窗口并手动调用命令,你可以在每个提示符上显示时间戳,例如:

prompt $d $t $_$P$G

它会给你这样的东西:

# EYZ0

# EYZ0

如果你有一个小的批处理脚本来执行你的命令,在每个命令之前有一个空行,例如。

(空行)

myCommand.exe

(下一行空)

myCommand2.exe

根据提示符中的时间信息,可以计算出每条命令的执行时间。最好的可能是管道输出到一个文本文件进行进一步分析:

MyBatchFile.bat > output.txt

如果您使用的是Windows 2003(注意不支持Windows server 2008及更高版本),您可以使用Windows server 2003资源工具包,其中包含显示详细执行统计信息的time .exe。下面是一个例子,计时命令&;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

您可以在Windows 2003资源工具包中获得TimeIt。它不能从微软下载中心直接下载,但人们仍然可以从archive.org - Windows Server 2003资源工具包工具中获得它。

  1. 在您的程序所在的目录中,键入notepad mytimer.bat,单击“是”创建一个新文件。

  2. 粘贴下面的代码,用你的程序替换YourApp.exe,然后保存。

    @echo off
    date /t
    time /t
    YourApp.exe
    date /t
    time /t
    
  3. Type mytimer.bat in the command line then press Enter.

我使用免费软件“GS定时器”。

只需要像这样做一个批处理文件:

timer
yourapp.exe
timer /s

如果您需要一组时间,只需将timer /s的输出输出到.txt文件中。

你可以在这里得到它:Gammadyne的免费DOS实用程序


分辨率为0.1秒。

呵呵,最简单的解决办法可能是:

echo %time%
YourApp.exe
echo %time%

这适用于所有开箱即用的Windows。


在应用程序使用控制台输出的情况下,将开始时间存储在临时变量中可能会很方便:

set startTime=%time%
YourApp.exe
echo Start Time: %startTime%
echo Finish Time: %time%

我在Windows Server 2008 R2中使用的一行程序是:

cmd /v:on /c "echo !TIME! & *mycommand* & echo !TIME!"

只要mycommand不需要引号(这会打乱cmd的引号处理)。/v:on允许两个不同的TIME值独立计算,而不是在执行命令时一次计算。

PowerShell有一个名为Measure-Command的cmdlet。您必须确保在运行PowerShell的机器上是可用的。

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捕获命令的输出。你可以使用Out-Default将输出重定向回控制台:

PS> Measure-Command { echo hi | Out-Default }
hi


Days              : 0
...

正如Makotoe注释的那样,Measure-Command返回一个TimeSpan对象,因此测量的时间被打印为一堆字段。你可以使用ToString()将对象格式化为时间戳字符串:

PS> (Measure-Command { echo hi | Out-Default }).ToString()
hi
00:00:00.0001318

如果在Measure-Command中的命令改变了控制台文本的颜色,使用[Console]::ResetColor()将其重置为正常。

只要不超过24小时…

@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.

如果有人来这里寻找这个问题的答案,有一个Windows API函数叫做GetProcessTimes()。编写一个小的C程序来启动这个命令、执行这个调用并返回进程时间,看起来并没有太多的工作。

如果你愿意

  1. 测量执行时间精确到(hh:mm:ss)的百分之一秒。ff格式)
  2. 不需要下载和安装资源包
  3. 看起来像一个巨大的DOS书呆子(谁不是呢)

尝试将以下脚本复制到一个新的批处理文件(例如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)

使用

如果你把timecmd.bat放在你路径中的一个目录中,你可以在任何地方调用它,像这样:

timecmd [your command]

如。

C:\>timecmd pause
Press any key to continue . . .
command took 0:0:1.18

如果你想做输出重定向,你可以这样引用命令:

timecmd "dir c:\windows /s > nul"

这应该可以处理从午夜之前到午夜之后运行的命令,但是如果您的命令运行了24小时或更长时间,则输出将是错误的。

由于其他人建议安装像免费软件和PowerShell这样的东西,你也可以安装Cygwin,这将使你可以访问许多基本的Unix命令,如时间:

abe@abe-PC:~$ time sleep 5


real    0m5.012s
user    0m0.000s
sys 0m0.000s

不知道Cygwin增加了多少开销。

我使用的是XP系统,由于某些原因time .exe不适合我。我找到了另一种选择——PTIME。这工作得很好。

http://www.pc-tools.net/win32/ptime/

的例子,

C:\> ptime


ptime 1.0 for Win32, Freeware - http://www.pc-tools.net/
Copyright(C) 2002, Jem Berkes <jberkes@pc-tools.net>


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 <jberkes@pc-tools.net>


===  cd ===
C:\


Execution time: 0.015 s
@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.

还有TimeMem(2012年3月):

这是一个Windows实用程序,它执行一个程序并显示它的内容 执行时间、内存使用和IO统计信息。这与

.

下面的脚本只使用“cmd.exe”,并输出从创建管道到脚本之前的进程退出的毫秒数。也就是说,输入你的命令,并将其输送到脚本中。例如:"timeout 3 | runtime. "Cmd”应该返回类似“2990”的内容。如果你同时需要运行时输出和stdin输出,在管道- ex之前重定向stdin: "dir /s 1>temp.txt | runtime. exe "Cmd”将把“dir”命令的输出转储到“temp.txt”,并将运行时打印到控制台。

:: --- 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

是对Luke Sampson漂亮的timecmd.bat的评论/编辑,并回复

出于某种原因,这只给我整秒的输出…这对我来说毫无用处。我的意思是,我运行timecmd pause,结果总是1秒,2秒,4秒……甚至是0.00秒!Windows 7。- Camilo Martin 13年9月25日16:00

在某些配置上,分隔符可能不同。以下变化至少应该涵盖大多数西方国家。

set options="tokens=1-4 delims=:,." (added comma)

在我的系统上添加了%time%毫秒后,

(*因为网站不允许匿名评论,没有很好地跟踪身份,即使我总是使用相同的客人电子邮件,结合ipv6 ip和浏览器指纹应该足以唯一识别没有密码)

下面的脚本模拟*nix纪元时间,但它是本地和区域性的。它应该处理日历边缘情况,包括闰年。如果Cygwin可用,则可以通过指定Cygwin选项来比较epoch值。

我在EST,报告的差异是4小时,这是相对正确的。有一些有趣的解决方案可以删除TZ和区域依赖,但我注意到没有什么微不足道的。

@ECHO off
SETLOCAL EnableDelayedExpansion


::
::  Emulates local epoch seconds
::


:: Call passing local date and time
CALL :SECONDS "%DATE%" "%TIME%"
IF !SECONDS! LEQ 0 GOTO END


:: Not testing - print and exit
IF NOT "%~1"=="cygwin" (
ECHO !SECONDS!
GOTO END
)


:: Call on Cygwin to get epoch time
FOR /F %%c IN ('C:\cygwin\bin\date +%%s') DO SET EPOCH=%%c


:: Show the results
ECHO Local Seconds: !SECONDS!
ECHO Epoch Seconds: !EPOCH!


:: Calculate difference between script and Cygwin
SET /A HOURS=(!EPOCH!-!SECONDS!)/3600
SET /A FRAC=(!EPOCH!-!SECONDS!)%%3600


:: Delta hours shown reflect TZ
ECHO Delta Hours: !HOURS! Remainder: !FRAC!


GOTO END


:SECONDS
SETLOCAL  EnableDelayedExpansion


:: Expecting values from caller
SET DATE=%~1
SET TIME=%~2


:: Emulate Unix epoch time without considering TZ
SET "SINCE_YEAR=1970"


:: Regional constraint! Expecting date and time in the following formats:
::   Sun 03/08/2015   Day MM/DD/YYYY
::   20:04:53.64         HH:MM:SS
SET VALID_DATE=0
ECHO !DATE! | FINDSTR /R /C:"^... [0-9 ][0-9]/[0-9 ][0-9]/[0-9][0-9][0-9][0-9]" > nul && SET VALID_DATE=1
SET VALID_TIME=0
ECHO !TIME! | FINDSTR /R /C:"^[0-9 ][0-9]:[0-9 ][0-9]:[0-9 ][0-9]" > nul && SET VALID_TIME=1
IF NOT "!VALID_DATE!!VALID_TIME!"=="11" (
IF !VALID_DATE! EQU 0  ECHO Unsupported Date value: !DATE! 1>&2
IF !VALID_TIME! EQU 0  ECHO Unsupported Time value: !TIME! 1>&2
SET SECONDS=0
GOTO SECONDS_END
)


:: Parse values
SET "YYYY=!DATE:~10,4!"
SET "MM=!DATE:~4,2!"
SET "DD=!DATE:~7,2!"
SET "HH=!TIME:~0,2!"
SET "NN=!TIME:~3,2!"
SET "SS=!TIME:~6,2!"
SET /A YEARS=!YYYY!-!SINCE_YEAR!
SET /A DAYS=!YEARS!*365


:: Bump year if after February  - want leading zeroes for this test
IF "!MM!!DD!" GEQ "0301" SET /A YEARS+=1


:: Remove leading zeros that can cause octet probs for SET /A
FOR %%r IN (MM,DD,HH,NN,SS) DO (
SET "v=%%r"
SET "t=!%%r!"
SET /A N=!t:~0,1!0
IF 0 EQU !N! SET "!v!=!t:~1!"
)


:: Increase days according to number of leap years
SET /A DAYS+=(!YEARS!+3)/4-(!SINCE_YEAR!%%4+3)/4


:: Increase days by preceding months of current year
FOR %%n IN (31:1,28:2,31:3,30:4,31:5,30:6,31:7,31:8,30:9,31:10,30:11) DO (
SET "n=%%n"
IF !MM! GTR !n:~3! SET /A DAYS+=!n:~0,2!
)


:: Multiply and add it all together
SET /A SECONDS=(!DAYS!+!DD!-1)*86400+!HH!*3600+!NN!*60+!SS!


:SECONDS_END
ENDLOCAL & SET "SECONDS=%SECONDS%"
GOTO :EOF


:END
ENDLOCAL

只是一点点扩展凯西的回答。K使用PowerShellMeasure-Command:

  1. 您可以从标准命令提示符调用PowerShell,如下所示:

    powershell -Command "Measure-Command {echo hi}"
    
  2. 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}
    

    或者从命令提示符:

    powershell -Command "Measure-Command {echo hi | Out-Default}"
    

Of course, you're free to wrap this in a script file *.ps1 or *.bat.

这是一个单行程序,避免了推迟扩张,这可能会扰乱某些命令:

cmd /E /C "prompt $T$$ & echo.%TIME%$ & COMMAND_TO_MEASURE & for %Z in (.) do rem/ "

输出如下所示:

14:30:27.58$
...
14:32:43.17$ rem/

对于长期测试,将$T替换为$D, $T,将%TIME%替换为%DATE%, %TIME%以包含日期。

要在批处理文件中使用,请将%Z替换为%%Z


更新

这是一个改进的一行程序(没有推迟扩张):

cmd /E /C "prompt $D, $T$$ & (for %# in (.) do rem/ ) & COMMAND_TO_MEASURE & for %# in (.) do prompt"

输出如下所示:

2015/09/01, 14:30:27.58$ rem/
...
2015/09/01, 14:32:43.17$ prompt

这种方法不包括在结果中实例化一个新的cmd的过程,也不包括prompt命令。

driblio的答案可以更短一些(尽管可读性不高)

@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

对于Luke Sampson的备注来说,这个版本是八进制安全的,尽管任务应该在24小时内完成。

这是一个

后置计时器版本:

使用的例子:

# EYZ0 # EYZ1

Execution took  ~969 milliseconds.

及复印件;将它粘贴到一些编辑器中,例如notepad++,并保存为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

^ -基于《丹尼尔·斯帕克斯》版本

下面是我的方法,没有转换和没有ms。它有助于确定编码持续时间(限制在24小时内):

@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

用潜水艇返回百分之一秒的时间

::tiemeit.cmd
@echo off
Setlocal EnableDelayedExpansion


call :clock


::call your_command  or more > null to pipe this batch after your_command


call :clock


echo %timed%
pause
goto:eof


:clock
if not defined timed set timed=0
for /F "tokens=1-4 delims=:.," %%a in ("%time%") do (
set /A timed = "(((1%%a - 100) * 60 + (1%%b - 100)) * 60 + (1%%c - 100))  * 100 + (1%%d - 100)- %timed%"
)
goto:eof
< p > # EYZ0 < br > 适应Aacini的替换方法体,没有IF,只有一个FOR(我的区域修复)

1:文件timer.bat放置在%PATH%或当前目录的某处

@echo off & rem :AveYo: compact timer function with Regional format, 24-hours and mixed input support
if not defined timer_set (if not "%~1"=="" (call set "timer_set=%~1") else set "timer_set=%TIME: =0%") & goto :eof
(if not "%~1"=="" (call set "timer_end=%~1") else set "timer_end=%TIME: =0%") & setlocal EnableDelayedExpansion
for /f "tokens=1-6 delims=0123456789" %%i in ("%timer_end%%timer_set%") do (set CE=%%i&set DE=%%k&set CS=%%l&set DS=%%n)
set "TE=!timer_end:%DE%=%%100)*100+1!"     & set "TS=!timer_set:%DS%=%%100)*100+1!"
set/A "T=((((10!TE:%CE%=%%100)*60+1!%%100)-((((10!TS:%CS%=%%100)*60+1!%%100)" & set/A "T=!T:-=8640000-!"
set/A "cc=T%%100+100,T/=100,ss=T%%60+100,T/=60,mm=T%%60+100,hh=T/60+100"
set "value=!hh:~1!%CE%!mm:~1!%CE%!ss:~1!%DE%!cc:~1!" & if "%~2"=="" echo/!value!
endlocal & set "timer_end=%value%" & set "timer_set=" & goto :eof
< p >用法:< br > 计时器 ,Echo start_cmds &超时/t 3 &Echo end_cmds & 计时器
# EYZ0,# EYZ0“23:23:23,00”< br > 计时器 "23:23:23,00" &# EYZ0 < br > 计时器 "13.23.23,00" &# EYZ0 03:03:03.00“< br > # EYZ0,计时器“0:00:00.00”没有&CMD /v:on /c echo until midnight=!timer_end!< br > 输入现在可以混合,对于那些不太可能,但在执行期间可能的时间格式更改

2:函数:定时器与批处理脚本捆绑(示例用法如下):

@echo off
set "TIMER=call :timer" & rem short macro
echo.
echo EXAMPLE:
call :timer
timeout /t 3 >nul & rem Any process here..
call :timer
echo.
echo SHORT MACRO:
%TIMER% & timeout /t 1 & %TIMER%
echo.
echo TEST INPUT:
set "start=22:04:04.58"
set "end=04.22.44,22"
echo %start% ~ start & echo %end% ~ end
call :timer "%start%"
call :timer "%end%"
echo.
%TIMER% & %TIMER% "00:00:00.00" no
echo UNTIL MIDNIGHT: %timer_end%
echo.
pause
exit /b

:: # EYZ0

rem :AveYo: compact timer function with Regional format, 24-hours and mixed input support
:timer Usage " call :timer [input - optional] [no - optional]" :i Result printed on second call, saved to timer_end
if not defined timer_set (if not "%~1"=="" (call set "timer_set=%~1") else set "timer_set=%TIME: =0%") & goto :eof
(if not "%~1"=="" (call set "timer_end=%~1") else set "timer_end=%TIME: =0%") & setlocal EnableDelayedExpansion
for /f "tokens=1-6 delims=0123456789" %%i in ("%timer_end%%timer_set%") do (set CE=%%i&set DE=%%k&set CS=%%l&set DS=%%n)
set "TE=!timer_end:%DE%=%%100)*100+1!"     & set "TS=!timer_set:%DS%=%%100)*100+1!"
set/A "T=((((10!TE:%CE%=%%100)*60+1!%%100)-((((10!TS:%CS%=%%100)*60+1!%%100)" & set/A "T=!T:-=8640000-!"
set/A "cc=T%%100+100,T/=100,ss=T%%60+100,T/=60,mm=T%%60+100,hh=T/60+100"
set "value=!hh:~1!%CE%!mm:~1!%CE%!ss:~1!%DE%!cc:~1!" & if "%~2"=="" echo/!value!
endlocal & set "timer_end=%value%" & set "timer_set=" & goto :eof

CE,DE和CS,DS代表冒号结束,点结束和冒号集合,点集合-用于混合格式支持

我的代码为您提供以毫秒为单位的运行时间,最高可达24小时,它是地区不敏感的,如果代码运行到午夜,则为负值。它使用延迟扩展,应该保存在cmd/bat文件中。

代码之前:

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%

代码之后:

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

如果你想让运行时间以HH:mm:ss为单位。000格式,添加:

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

变量t2保存您的运行时间,您可以echo %t2%显示它。

测量时间的替代方法是简单的“Get-Date”。你不会有转发输出的麻烦。

$start = Get-Date
[System.Threading.Thread]::Sleep(1500)
$(Get-Date) - $start

输出:

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

根据您使用的Windows版本不同,只需运行bash即可进入Bash模式。这将允许您使用许多在PowerShell上不能直接使用的命令(如time命令)。计时你的命令现在像执行一样简单:

# The clause <your-command> (without the angle brackets) denotes the command you want to run.
$ time <your-command>

在Bash模式下运行exit可以轻松退出Bash模式并返回到主流shell。

这对我来说非常有效(Windows 10),在尝试了其他方法(如Measure-Command)后,有时会产生不需要的统计数据。希望这对你也有用。

在Perl安装了可用的雇佣解决方案后,运行:

C:\BATCH>time.pl "echo Fine result"
0.01063
Fine result

STDERR出现在被测量的秒之前

#!/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;

一个解决方案使用纯PHP为cmd和一个env。变量:

@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('&#13;&#10;', 'UTF-8', 'HTML-ENTITIES');"
  • 不需要cygwin或不受信任的实用程序。当PHP在本地可用时非常有用

  • 精度和输出格式可以很容易地调整

  • 同样的想法也可以移植到PowerShell

powershell的另一种方法:

@echo off
for /f %%t in ('powershell "(get-date).tofiletime()"') do set mst=%%t


rem some commands


powershell ((get-date).tofiletime() - %mst%)

这将以毫秒为单位打印执行时间。

如果安装了CMake,可以只运行以下命令。

cmake -E time <the_command_to_measure_run_time>