How do I measure execution time of a command on the Windows command line?

后端 未结 30 2942
南笙
南笙 2020-11-22 09:44

Is there a built-in way to measure execution time of a command on the Windows command line?

相关标签:
30条回答
  • 2020-11-22 10:18

    The following script emulates *nix epoch time, but it is local and regional. It should handle calender edge cases including leap years. If Cygwin is available, epoch values can be compared by specifying the Cygwin option.

    I'm in EST and the difference reported is 4 hours which is relatively correct. There are some interesting solutions to remove the TZ and regional dependencies, but nothing trivial that I noticed.

    @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
    
    0 讨论(0)
  • 2020-11-22 10:19

    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%
    
    0 讨论(0)
  • 2020-11-22 10:19

    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
    
    0 讨论(0)
  • 2020-11-22 10:20

    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:
    
    0 讨论(0)
  • 2020-11-22 10:20

    "Lean and Mean" TIMER with Regional format, 24h and mixed input support
    Adapting Aacini's substitution method body, no IF's, just one FOR (my regional fix)

    1: File timer.bat placed somewhere in %PATH% or the current dir

    @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
    

    Usage:
    timer & echo start_cmds & timeout /t 3 & echo end_cmds & timer
    timer & timer "23:23:23,00"
    timer "23:23:23,00" & timer
    timer "13.23.23,00" & timer "03:03:03.00"
    timer & timer "0:00:00.00" no & cmd /v:on /c echo until midnight=!timer_end!
    Input can now be mixed, for those unlikely, but possible time format changes during execution

    2: Function :timer bundled with the batch script (sample usage below):

    @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
    

    :: to test it, copy-paste both above and below code sections

    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 and CS,DS stand for colon end, dot end and colon set, dot set - used for mixed format support

    0 讨论(0)
  • 2020-11-22 10:24

    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.

    0 讨论(0)
提交回复
热议问题