Jak zmierzyć czas wykonania polecenia w wierszu poleceń systemu Windows?


Odpowiedzi:


113

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 .


7
Ten zestaw ma problemy z Windows 2008 64bit i nie działa w 2008 R2
Artem

czy jest jakiś sposób pomiaru czasu jądra i / lub czasu wykorzystywanego przez odradzane podprocesy?
rogerdpack

38
Do Twojej wiadomości - nie sądzę, że timeit działa na 64-bitowym systemie Windows 7. Pojawia się błąd „Nie można wysłać zapytania o dane o wydajności systemu (c0000004). Zamiast tego użyj polecenia„ Measure-Command ”programu PowerShell, takiego jak Casey.K sugeruje: stackoverflow.com/questions/673523/…
Michael La Voie

6
W systemie Windows 7 widzę, że „timeit” nie jest rozpoznawany jako polecenie wewnętrzne lub zewnętrzne, program operacyjny lub plik wsadowy. ”
Pułkownik Panic

3
Nie widzę polecenia w systemie Windows 10, ani nie mogę łatwo znaleźć zestawu zasobów dla systemu Windows 10. Czy ktoś wie, jak uzyskać ten zestaw dla systemu 10?
Jay Imerman

469

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

21
Jest to najlepsze rozwiązanie dla użytkowników systemu Windows 7, ponieważ timeit.exe nie obsługuje systemu Windows 7
Michael La Voie

14
Jeśli chcesz użyć wewnętrznych poleceń dos (np .: dir, echo, del, itp.), Nie zapomnij wstawić „cmd / c”: Measure-Command {cmd / c dir / sc: \ windows> nul}
LietKynes,

7
Jeśli benchmarking .exew bieżącym katalogu, użyj tego: Measure-Command { .\your.exe }. PowerShell najwyraźniej nie uruchamia rzeczy, pwdchyba że jest to wyraźnie nakazane.
Cristian Diaconescu,

13
Irytujące jednak kryje stdout.
Zitrax,

13
To wcale NIE jest narzędzie „podobne do polecenia czasu Basha” . Fajnie jest wiedzieć… ale: nie wykonuje się i nie wraca do<stdout> wyników polecenia zawartego w nawiasach klamrowych!
Kurt Pfeifle

287

Jeśli chcesz

  1. Aby zmierzyć czas wykonania do setnych sekundy w (gg: mm: ss.ff format)
  2. Nie trzeba pobierać i instalować pakietu zasobów
  3. Aby wyglądać jak wielki nerd DOS (który nie)

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.


9
zastępując cmd / c% * z % * roboty, chyba że polecenie jest inny plik wsadowy. Potem musisz zadzwonić
Jesse Chisholm

2
@JesseChisholm W systemie Windows 8 (i czytałem również w systemie Windows 7) nie potrzebujesz połączenia z .bat
Brian J

4
Z jakiegoś powodu daje mi to wynik tylko w ciągu kilku sekund ... co jest dla mnie bezużyteczne. Mam na myśli to, że biegam timecmd pause, a to zawsze skutkuje 1,00 sek., 2,00 sek., 4,00 sek ... nawet 0,00 sek! Windows 7.
Camilo Martin

9
@CamiloMartin i inni, którzy mieli to (jak ja) - możesz mieć ustawienia narodowe, które używają COMMA zamiast DOT do dziesiętnego. Tak więc w tym zdrapce zmień delims=:.na delims=:.,, a potem powinno działać „na całej planszy”.
Tomasz Gandor,

5
W tym skrypcie występuje poważny błąd arytmetyczny: Wypróbuj go: set start=10:10:10.10 set end=10:11:10.09I 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)
wygląda następująco

230

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%

163
Oszalałeś?! To wymaga robienia matematyki w mózgu. Właśnie dlatego wynaleźliśmy komputery, abyśmy mogli uniknąć takich rzeczy.
Luke Sampson

1
znakomity! Chociaż czas procesora tak naprawdę nie pomaga
Elijah Saounkine

10
Jeszcze lepiej (jeśli twoja aplikacja wypluwa dane wyjściowe do konsoli): 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)
Jono

1
@LukeSampson, możesz użyć setdo wykonania matematyki. ;-)Och, czekaj, nieważne, już to zrobiłeś poniżej.
Synetech

2
Nie, to zła opcja. To pokazuje czas zegara ściennego, a nie czas procesora. Tak więc, nawet jeśli twoja linia poleceń może zająć tylko 100ms, jeśli inna aplikacja blokuje procesor, twoja aplikacja może potrwać kilka sekund (wyłączona o 100x lub więcej). W rzeczywistości, jeśli Twój komputer jest wstrząsający, możesz nawet chwilę poczekać na uruchomienie małej aplikacji 100ms. Śledź czas procesora, a nie zegar ścienny!
Ryan Shillington

102

Małe rozszerzenie odpowiedzi Casey.K na temat korzystania Measure-Commandz programu PowerShell :

  1. Możesz wywołać PowerShell ze standardowego wiersza poleceń, w następujący sposób:

    powershell -Command "Measure-Command {echo hi}"
    
  2. Spowoduje to zjedzenie standardowego wyjścia, ale można temu zapobiec, dodając w | Out-Defaultten 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 *.ps1lub *.bat.


1
Co jeśli polecenie, które chcemy zmierzyć, zawiera cudzysłowy? Czy w takim przypadku można to zmienić na skrypt .bat? Na przykładmeasureTime.bat "c:\program files\some dir\program.exe"
GetFree,

53

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:onto na celu umożliwienie niezależnej oceny dwóch różnych wartości CZASU, a nie jednorazowego wykonania polecenia.


To również nie zadziała dla partii „spamu”, które zastępują etykietę za pierwszym razem i sugerują, że zastępujesz komputer wykonujący obliczenia, jak zauważono w stackoverflow.com/questions/673523/…
Val

Zazwyczaj możesz uciec od cudzysłowów ^w cmd (jak ^")
n611x007

2
Jeśli powtórzysz cmd / v: on dla drugiego taktu , możemy nawet poprosić, aby moja komenda zawierała cytaty. Przykład: cmd /v:on /c echo !TIME! & echo "Quoted mycommand" & cmd /v:on /c echo !TIME!.
Maarten Pennings

8
Prostsze: echo %time% & *mycommand* & call echo %^time%. Zobacz także tę odpowiedź .
Aacini,

Jeśli twoje polecenie generuje zbyt wiele, być może łatwiej jest po prostu połączyć 2 razem:cmd /v:on /c "mycommand & echo begin=%time% endtime=!time!"
ZHANG Zikai

49

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

3
Pomyślałem, że za kilka lat zostanę za dyskusją, aby podziękować za podzielenie się szybkim poleceniem. Widziałem wiele sztuczek CMD (bardziej bash facet), ale ten uniknął mojej uwagi.
Steve Howard,

Prosty, elegancki, bez instalacji i bez zapisywania plików wsadowych dla jednego polecenia i może mierzyć każdy krok w pliku wsadowym.
Matt

26

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.


41
Odpowiadając na pytania dotyczące systemu Windows, Cygwin uważa się za oszustwo :-)
mivk,

14
Stwierdził, że ResourceKit, TimeMem, ptime.exe, PowerShell i inne narzędzia, które użytkownicy zaczęli oszukiwać jako pierwsze. Dlatego autor uczynił twój komentarz nieodpowiednim przed napisaniem go.
Val

Poparłem to również, ponieważ uważałem to za najłatwiejsze rozwiązanie, ponieważ bezpłatny program Cmder zawiera bash! cmder.net Pamiętaj tylko, że jeśli chcesz uciec przed spacjami, użyj blackslash \ tuż przed spacją, zamiast „cudzysłowów”. np. cd / c / Program \ Files /
lukescammell

24

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:

2
Zakładając, że nie potrzebujesz przenośności w różnych językach, możesz także umieścić findstr „current” lub coś takiego po „time <nul” (przy okazji fajne użycie nul; zawsze używałem echa. | Time, ale to nie wygląda tak elegancko :)). I użyj „for”, aby wyodrębnić tylko czas, a nie tekst.
Joey

2
Jeśli rozszerzenia poleceń są włączone (to jest domyślne), wersja Win XP timema /topcję, 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.)
martineau,

3
time /Tjest użyteczny tylko wtedy, gdy proces trwa kilka minut! time < nuljest brzydszy, ale bardziej precyzyjny.
PhiLho,

6
Możesz także użyć tego, echo %time%który zapewnia ten sam format i precyzję time < nul, ale unikasz danych Enter the new time:wyjściowych ...
aschipfl

dla niezależnego od lokalizacji i bardziej precyzyjnego wykorzystania czasuwmic os get LocalDateTime
phuclv

19

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.


4
Nie sądzę, aby korzystanie z aplikacji innej firmy można było zrobić „standardowymi środkami”.
martineau,

4
Pytający miał na myśli „bez instalowania dodatkowego oprogramowania”, ale górna (zaakceptowana) odpowiedź wymaga również zainstalowania całego zestawu Windows 2003 Resource Kit! W każdym razie timer.exe był idealny do tego, czego właśnie szukałem, dzięki!
Hugo

1
To jest posadzony link. SoftPedia to farma kliknięć.
Tom A

@ Tom, proszę wyjaśnić, co masz na myśli „podłożył link”?
pepoluan

10
Oto bezpośredni link do własnej strony programisty: gammadyne.com/cmdline.htm#timer
Hugo

14

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

Działa również w systemie Windows 8.1. Nazwa moja została zmieniona na timer.exe, ponieważ nigdy nie pamiętam nazwy ptime.
Brian Burns,

11

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.


10

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.

5
Imponujące, ale nie sądzę, aby to zadziałało, jeśli w czasach rozpoczęcia lub zakończenia jest 08 lub 09, ponieważ są one interpretowane jako ósemki. Moja odpowiedź sobie z tym radzi :)
Luke Sampson

6

Tutaj jest

Wersja timera Postfix:

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”


5

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

To było dla mnie idealne
Brett Rowberry,

4

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ć $Tprzez $D, $Ti %TIME%przez %DATE%, %TIME%zawierać datę.

Aby użyć tego w pliku wsadowym , zamień %Zna %%Z.


Aktualizacja

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 cmdwyniku ani promptpolecenia.


4

W zależności od używanej wersji systemu Windows samo uruchomienie bashspowoduje 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 timepolecenie). 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 exitw 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.


2
Od Windows 10 1607 najlepsza odpowiedź.
CarpeDiemKopi

2

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.


3
Pobranie małego programu C, który uruchomi polecenie, wykona to wywołanie (i znacznie więcej wcześniejszych pomiarów) i zwróci czasy procesu, nie wydaje się zbyt dużym nakładem pracy.
Elazar Leibovich

@ElazarLeibovich powershell? Możesz to nazwać z C #.
KeyWeeUsr 10.04.17

@KeyWeeUsr możesz używać Windows API IIRC z PS blogs.technet.microsoft.com/heyscriptingguy/2013/06/25/…
Elazar Leibovich

2

To jest komentarz / edycja do miłej timecmd.batodpowiedzi 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)


Skomentowałem to przed przewinięciem do odpowiedzi. W każdym razie skrypt Luke'a mógłby zerować godziny, minuty i sekundy, nie tylko podsekundy (które są w centisekundach , a nie milisekundach, BTW). Zobacz tutaj: en.wiktionary.org/wiki/centisecond
Tomasz Gandor

2

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

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

Nie działa. Uzyskiwanie: niezrównoważony nawias. Niezrównoważony nawias. Brakujący operand.
Richard Sandoz,

@RichardSandoz Działa dobrze, nie ma niezrównoważonego nawiasu. Jak go używasz?
MikeM

1

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

Zamiast rekurencyjnego wywoływania skryptu, rozważ zrobienie tego w ten sposób call :calc. Zrobiłem to tutaj. link code get to co jest ładniejsze w ten sposób. : D
Nadu,

Błąd nr 1 zawiedzie o 12 godzinie. Przykład: „ 0 : 23: 19,42” Błąd nr 2 Błąd, jeśli przecinek dziesiętny jest inny niż. ten sam przykład: „0:23:19 , 42” tutaj kropka dziesiętna to: <__________> Próbowałem jednak edytować ten głupi **** w „komisji zatwierdzającej edycję” odrzucił ją - 3 z 5 głosowało „Ta edycja również się zmienia wiele pierwotnych intencji autorów ”. więc jeśli masz ochotę wypróbować swoje szczęście lub po prostu trzymaj błędy w sobie - tak „oryginalna intencja autorów pozostaje nienaruszona”. facepalm
Nadu

Nie można wyprowadzać milisekund, gdy rozdzielczość twojego zegara ledwo jest w stanie uzyskać rozdzielczość 1/100 sekundy.
jwdonahue

1

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.


Nie działa. Brak operatora, gdy jednocyfrowa godzina.
Richard Sandoz,

set _time=%time: =0%naprawia problem jednocyfrowej godziny - wymień w obu miejscach.
Laur

1
  1. W katalogu, w którym znajduje się twój program, wpisz notepad mytimer.bat„tak”, aby utworzyć nowy plik.

  2. Wklej poniższy kod, zastępując YourApp.exego programem, a następnie zapisz.

    @echo off
    date /t
    time /t
    YourApp.exe
    date /t
    time /t
  3. Wpisz mytimer.batwiersz polecenia, a następnie naciśnij klawisz Enter.


7
time / t daje tylko czas w GG: MM. Aby określić czas wykonywania pliku, zwykle potrzebujesz większej dokładności ... Czy to coś, co możesz skonfigurować, aby sprowadzać się do ułamków sekundy? Testowałem rozwiązanie z JohnW (czas <nul), a to faktycznie daje czas do 1/100: HH: MM: SS.XX
awe

1

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 t2przechowuje twój czas działania, możesz echo %t2%go wyświetlić.


1

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;

0

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

0

„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


0

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

Ciekawy o głosowaniu. Dzięki.
bvj

0

Rozwiązanie wykorzystujące czysty PHP dla cmd i jednego środowiska. zmienna:

@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');"
  • 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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.