Czy istnieje wbudowany sposób pomiaru czasu wykonywania polecenia w wierszu poleceń systemu Windows?
Czy istnieje wbudowany sposób pomiaru czasu wykonywania polecenia w wierszu poleceń systemu Windows?
Odpowiedzi:
Jeśli używasz systemu Windows 2003 (pamiętaj, że Windows Server 2008 i nowsze wersje nie są obsługiwane), możesz użyć zestawu Windows Server 2003 Resource Kit, który zawiera timeit.exe, który wyświetla szczegółowe statystyki wykonania. Oto przykład synchronizacji polecenia „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
Możesz uzyskać TimeIt w zestawie Windows 2003 Resource Kit. Pobierz tutaj .
Alternatywnie, Windows PowerShell ma wbudowane polecenie podobne do polecenia „czas” Basha. Nazywa się to „Measure-Command”. Musisz upewnić się, że PowerShell jest zainstalowany na komputerze, na którym jest uruchomiony.
Przykładowe dane wejściowe:
Measure-Command {echo hi}
Przykładowe dane wyjściowe:
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
.exe
w bieżącym katalogu, użyj tego: Measure-Command { .\your.exe }
. PowerShell najwyraźniej nie uruchamia rzeczy, pwd
chyba że jest to wyraźnie nakazane.
<stdout>
wyników polecenia zawartego w nawiasach klamrowych!
Jeśli chcesz
Spróbuj skopiować następujący skrypt do nowego pliku wsadowego (np. 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)
Stosowanie
Jeśli umieścisz timecmd.bat w katalogu na swojej ścieżce, możesz wywołać go z dowolnego miejsca takiego jak to:
timecmd [your command]
Na przykład
C:\>timecmd pause
Press any key to continue . . .
command took 0:0:1.18
Jeśli chcesz wykonać przekierowanie danych wyjściowych, możesz zacytować polecenie w następujący sposób:
timecmd "dir c:\windows /s > nul"
Powinno to obsługiwać polecenia uruchamiane przed północą i po północy, ale dane wyjściowe będą niepoprawne, jeśli polecenie będzie działać przez 24 godziny lub dłużej.
timecmd pause
, a to zawsze skutkuje 1,00 sek., 2,00 sek., 4,00 sek ... nawet 0,00 sek! Windows 7.
delims=:.
na delims=:.,
, a potem powinno działać „na całej planszy”.
set start=10:10:10.10
set end=10:11:10.09
I wyświetli: command took 0:1:-1.99 (59.99s total)
Powinieneś odwrócić kolejność 4 linii, które wykonują porównania „lss 0”, aby przenoszenie przebiegało poprawnie od niskich do wysokich cyfr płciowych. Następnie wynik command took 0:0:59.99 (59.99s total)
Hehe, najprostszym rozwiązaniem może być to:
echo %time%
YourApp.exe
echo %time%
Działa to na każdym systemie Windows od razu po wyjęciu z pudełka.
W przypadku aplikacji korzystającej z danych wyjściowych konsoli wygodne może być przechowywanie czasu rozpoczęcia w zmiennej tymczasowej:
set startTime=%time%
YourApp.exe
echo Start Time: %startTime%
echo Finish Time: %time%
set startTime=%time% \n YourApp.exe \n echo Start Time: %startTime% \n echo Finish Time: %time%
(Niestety, nie mogłem uzyskać nowych linii w komentarzu)
set
do wykonania matematyki. ;-)
Och, czekaj, nieważne, już to zrobiłeś poniżej.
Małe rozszerzenie odpowiedzi Casey.K na temat korzystania Measure-Command
z programu PowerShell :
Możesz wywołać PowerShell ze standardowego wiersza poleceń, w następujący sposób:
powershell -Command "Measure-Command {echo hi}"
Spowoduje to zjedzenie standardowego wyjścia, ale można temu zapobiec, dodając w | Out-Default
ten sposób program PowerShell:
Measure-Command {echo hi | Out-Default}
Lub z wiersza polecenia:
powershell -Command "Measure-Command {echo hi | Out-Default}"
Oczywiście możesz zawinąć to w plik skryptu *.ps1
lub *.bat
.
measureTime.bat "c:\program files\some dir\program.exe"
Jednowierszowy, którego używam w systemie Windows Server 2008 R2 to:
cmd /v:on /c "echo !TIME! & *mycommand* & echo !TIME!"
Tak długo, jak moja komenda nie wymaga cudzysłowów (co przekręca się przy przetwarzaniu ofert cmd). Ma /v:on
to na celu umożliwienie niezależnej oceny dwóch różnych wartości CZASU, a nie jednorazowego wykonania polecenia.
^
w cmd (jak ^"
)
cmd /v:on /c echo !TIME! & echo "Quoted mycommand" & cmd /v:on /c echo !TIME!
.
echo %time% & *mycommand* & call echo %^time%
. Zobacz także tę odpowiedź .
cmd /v:on /c "mycommand & echo begin=%time% endtime=!time!"
Jeśli masz otwarte okno poleceń i ręcznie wywołujesz polecenia, możesz wyświetlić znacznik czasu w każdym monicie, np
prompt $d $t $_$P$G
Daje ci coś takiego:
23.03.2009 15:45:50,77
C:\>
Jeśli masz mały skrypt wsadowy, który wykonuje twoje polecenia, przed każdą komendą miej pusty wiersz, np
(pusta linia)
myCommand.exe
(następny pusty wiersz)
myCommand2.exe
Czas wykonania każdego polecenia można obliczyć na podstawie informacji o czasie w monicie. Prawdopodobnie najlepiej byłoby przesłać dane wyjściowe do pliku tekstowego w celu dalszej analizy:
MyBatchFile.bat > output.txt
Ponieważ inni zalecają instalowanie rzeczy takich jak freeware i PowerShell, możesz również zainstalować Cygwin , który dałby ci dostęp do wielu podstawowych poleceń Uniksa, takich jak czas :
abe@abe-PC:~$ time sleep 5
real 0m5.012s
user 0m0.000s
sys 0m0.000s
Nie jestem pewien, ile dodaje narzut Cygwin.
Nie tak elegancki jak niektóre funkcje Uniksa, ale utwórz plik cmd, który wygląda następująco:
@echo off
time < nul
yourexecutable.exe > c:\temp\output.txt
time < nul
rem on newer windows system you can try time /T
Zostaną wyświetlone czasy rozpoczęcia i zakończenia w następujący sposób:
The current time is: 10:31:57.92
Enter the new time:
The current time is: 10:32:05.94
Enter the new time:
time
ma /t
opcję, która wyświetla aktualny czas systemowy, bez monitowania o wprowadzenie nowego czasu. Jednak gdy to zrobisz, wyświetla tylko godziny i minuty, co może nie być wystarczające dla niektórych zastosowań. (Zobacz odpowiedź Johna Snowa na to pytanie.)
time /T
jest użyteczny tylko wtedy, gdy proces trwa kilka minut! time < nul
jest brzydszy, ale bardziej precyzyjny.
echo %time%
który zapewnia ten sam format i precyzję time < nul
, ale unikasz danych Enter the new time:
wyjściowych ...
wmic os get LocalDateTime
Używam darmowego oprogramowania o nazwie „GS Timer”.
Utwórz plik wsadowy w ten sposób:
timer
yourapp.exe
timer /s
Jeśli potrzebujesz zestawu czasów, po prostu potokuj wyjście timera / s do pliku .txt.
Możesz go pobrać tutaj: Darmowe narzędzia Damm Gammadyne
Rozdzielczość wynosi 0,1 sekundy.
Korzystam z systemu Windows XP iz jakiegoś powodu timeit.exe nie działa dla mnie. Znalazłem inną alternatywę - PTIME. To działa bardzo dobrze.
http://www.pc-tools.net/win32/ptime/
Przykład -
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
Jest też TimeMem (marzec 2012):
Jest to narzędzie systemu Windows, które wykonuje program i wyświetla jego czas wykonania, zużycie pamięci oraz statystyki IO. Ma podobną funkcjonalność do narzędzia czasu Unix.
Tak długo, jak nie trwa to dłużej niż 24 godziny ...
@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.
Tutaj jest
Przykład użycia:
limit czasu 1 | TimeIt.cmd
Execution took ~969 milliseconds.
Skopiuj i wklej to do jakiegoś edytora, np. Notepad ++ i zapisz jako 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
^ - Na podstawie wersji „Daniel Sparks”
Alternatywą dla pomiaru czasu jest po prostu „Get-Date”. Nie masz problemów z przekazywaniem danych wyjściowych i tak dalej.
$start = Get-Date
[System.Threading.Thread]::Sleep(1500)
$(Get-Date) - $start
Wynik:
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
Jest to jedna linijka, która pozwala uniknąć opóźnionego rozszerzania , co mogłoby zakłócić niektóre polecenia:
cmd /E /C "prompt $T$$ & echo.%TIME%$ & COMMAND_TO_MEASURE & for %Z in (.) do rem/ "
Wynik jest podobny do:
14:30:27.58$ ... 14:32:43.17$ rem/
Na długoterminowe testy zastąpić $T
przez $D, $T
i %TIME%
przez %DATE%, %TIME%
zawierać datę.
Aby użyć tego w pliku wsadowym , zamień %Z
na %%Z
.
Oto ulepszony jednowarstwowy (bez opóźnionego rozszerzenia ):
cmd /E /C "prompt $D, $T$$ & (for %# in (.) do rem/ ) & COMMAND_TO_MEASURE & for %# in (.) do prompt"
Dane wyjściowe wyglądają podobnie do tego:
2015/09/01, 14:30:27.58$ rem/ ... 2015/09/01, 14:32:43.17$ prompt
To podejście nie obejmuje procesu tworzenia nowego cmd
wyniku ani prompt
polecenia.
W zależności od używanej wersji systemu Windows samo uruchomienie bash
spowoduje przejście do trybu Bash. Umożliwi to użycie zestawu poleceń, które nie są bezpośrednio dostępne w programie PowerShell (takich jak time
polecenie). Odmierzenie czasu polecenia jest teraz tak proste, jak wykonanie:
# The clause <your-command> (without the angle brackets) denotes the command you want to run.
$ time <your-command>
Uwaga: Możesz łatwo wyjść z trybu Bash i powrócić do powłoki głównego nurtu, działając
exit
w trybie Bash.
Działa to dla mnie idealnie (Windows 10) po wypróbowaniu innych metod (takich jak Measure-Command
), które czasami generują niepożądane statystyki. Mam nadzieję, że to również dla ciebie działa.
W przypadku, gdy ktoś tu przyszedł i szuka odpowiedzi na to pytanie, dostępna jest funkcja Windows API GetProcessTimes()
. Napisanie małego programu C, który uruchomi polecenie, wykona to wywołanie i zwróci czasy procesu, nie wygląda na zbyt wiele pracy.
To jest komentarz / edycja do miłej timecmd.bat
odpowiedzi Luke'a Sampsona
Z jakiegoś powodu daje mi to wynik tylko w ciągu kilku sekund ... co jest dla mnie bezużyteczne. Mam na myśli, że uruchamiam pauzę timecmd i zawsze powoduje to 1,00 s, 2,00 s, 4,00 s ... nawet 0,00 s! Windows 7. - Camilo Martin 25 września 13 'o 16:00
W niektórych konfiguracjach ograniczniki mogą się różnić. Następująca zmiana powinna obejmować co najmniej większość krajów zachodnich.
set options="tokens=1-4 delims=:,." (added comma)
The %time%
milisekund działa na moim systemie po dodając, że „”
(* ponieważ strona nie pozwala na komentowanie i nie śledzi tożsamości, nawet jeśli zawsze używam tego samego e-maila gościa, który w połączeniu z ipv6 ip i odciskiem palca przeglądarki powinien wystarczyć do jednoznacznej identyfikacji bez hasła)
Oto moja metoda, bez konwersji i bez ms. Przydatne jest określenie czasu trwania kodowania (ograniczony do 24 godzin):
@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
@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.
Poniższy skrypt używa tylko „cmd.exe” i wyświetla liczbę milisekund od momentu utworzenia potoku do zakończenia procesu poprzedzającego skrypt. tzn. wpisz polecenie i potokuj do skryptu. Przykład: „timeout 3 | runtime.cmd” powinien dać coś w rodzaju „2990”. Jeśli potrzebujesz zarówno danych wyjściowych środowiska wykonawczego, jak i danych wyjściowych stdin, przekieruj stdin przed potokiem - np .: „katalog / s 1> temp.txt | runtime.cmd” zrzuci dane wyjściowe polecenia „dir” na „temp.txt” i wydrukuje środowisko wykonawcze na konsoli.
:: --- 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
Odpowiedź driblio może być nieco krótsza (choć mało czytelna)
@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
Według uwagi Luke'a Sampsona ta wersja jest bezpieczna ósemkowo, choć zadanie powinno zostać ukończone w ciągu 24 godzin.
set _time=%time: =0%
naprawia problem jednocyfrowej godziny - wymień w obu miejscach.
W katalogu, w którym znajduje się twój program, wpisz notepad mytimer.bat
„tak”, aby utworzyć nowy plik.
Wklej poniższy kod, zastępując YourApp.exe
go programem, a następnie zapisz.
@echo off
date /t
time /t
YourApp.exe
date /t
time /t
Wpisz mytimer.bat
wiersz polecenia, a następnie naciśnij klawisz Enter.
mój kod podaje czas działania w milisekundach, do 24 godzin, jest niewrażliwy na ustawienia regionalne i uwzględnia ujemne wartości, jeśli kod działa do północy. wykorzystuje opóźnioną ekspansję i powinien być zapisany w pliku cmd / bat.
przed twoim kodem:
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%
po twoim kodzie:
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
jeśli chcesz mieć czas pracy w formacie GG: mm: ss.000, dodaj:
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
zmienna t2
przechowuje twój czas działania, możesz echo %t2%
go wyświetlić.
Po zainstalowaniu dostępnego rozwiązania wynajmu Perl uruchom:
C:\BATCH>time.pl "echo Fine result"
0.01063
Fine result
STDERR występuje przed zmierzonymi sekundami
#!/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;
Wykorzystanie sub do zwrócenia czasu w setnych sekundach
::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
„Lean and Mean” TIMER z formatem regionalnym, 24-godzinnym i mieszanym wejściem obsługuje
adaptację Aaciniego ciała metody zastępowania , bez IF, tylko jeden FOR (moja poprawka regionalna)
1: Plik timer.bat umieszczony gdzieś w% PATH% lub bieżącym katalogu
@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
Zastosowanie:
timer i echo start_cmds i timeout / t 3 i echo end_cmds i timer
timer i timer „23: 23: 23,00„
timer ”23: 23: 23,00” i timer
timera „13.23.23,00” i timer „03: 03: 03.00”
timer i timer „0: 00: 00.00” no & cmd / v: on / c echo do północy =! Timer_end!
Dane wejściowe mogą być teraz mieszane w przypadku tych mało prawdopodobnych, ale możliwych zmian formatu czasu podczas wykonywania
2: Funkcja : licznik czasu dołączony do skryptu wsadowego (przykładowe użycie poniżej):
@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
:: w celu przetestowania, skopiuj-wklej zarówno powyżej, jak i poniżej sekcji kodu
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 i CS, DS oznaczają koniec dwukropka, koniec kropki i zestaw dwukropka, zestaw kropek - używany do obsługi formatu mieszanego
Poniższy skrypt emuluje czas epoki * nix, ale jest lokalny i regionalny. Powinien obsługiwać przypadki krawędzi kalendarza, w tym lata przestępne. Jeśli Cygwin jest dostępny, wartości epoki można porównać, określając opcję Cygwin .
Jestem w EST, a zgłoszona różnica wynosi 4 godziny, co jest względnie poprawne. Istnieje kilka ciekawych rozwiązań pozwalających usunąć TZ i zależności regionalne, ale nie zauważyłem nic trywialnego.
@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
@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');"
nie potrzeba cygwina ani niezaufanych narzędzi. Przydatne, gdy PHP jest dostępne lokalnie
precyzję i format wyjściowy można łatwo dostosować
ten sam pomysł można przenieść do programu PowerShell