Come misurare il tempo di esecuzione di un comando sulla riga comandi di Windows?


Risposte:


113

Se si utilizza Windows 2003 (si noti che Windows Server 2008 e versioni successive non sono supportate) è possibile utilizzare il Resource Kit di Windows Server 2003, che contiene timeit.exe che visualizza statistiche dettagliate sull'esecuzione. Ecco un esempio, temporizzando il comando "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

È possibile ottenere TimeIt nel Resource Kit di Windows 2003. Scaricalo qui .


7
Questo kit presenta problemi con Windows 2008 a 64 bit e non funziona su 2008 R2
Artem,

esiste un modo per misurare anche il tempo del kernel e / o il tempo utilizzato dai processi secondari generati?
rogerdpack,

38
Cordiali saluti - Non credo che il timeit funzioni su Windows 7 a 64 bit. Si ottiene l'errore Measure-Command "come Casey.K suggerisce: "Impossibile dati di sistema di interrogazione di performance (c0000004) Utilizzare invece di PowerShell." Stackoverflow.com/questions/673523/...
Michael La Voie

6
In Windows 7 vedo che "'timeit' non è riconosciuto come comando interno o esterno, programma eseguibile o file batch."
Colonnello Panic,

3
Non vedo il comando in Windows 10, né trovo facilmente un Resource Kit per Win 10. Qualcuno sa come ottenerlo per 10?
Jay Imerman,

469

In alternativa, Windows PowerShell ha un comando integrato simile al comando "time" di Bash. Si chiama "Misura-comando". Dovrai assicurarti che PowerShell sia installato sul computer che lo esegue.

Esempio di input:

Measure-Command {echo hi}

Esempio di output:

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
Questa è la soluzione migliore per gli utenti di Windows 7 poiché timeit.exe non sembra supportare Windows 7
Michael La Voie,

14
Nel caso in cui si desideri utilizzare i comandi dos interni (es .: dir, echo, del, ecc.) Non dimenticare di inserire "cmd / c": Measure-Command {cmd / c dir / sc: \ windows> nul}
LietKynes,

7
Se stai analisi comparativa una .exenella directory corrente, utilizzare questo: Measure-Command { .\your.exe }. Apparentemente PowerShell non esegue le cose pwdse non esplicitamente detto.
Cristian Diaconescu,

13
Tuttavia, nasconde fastidiosamente stdout.
Zitrax,

13
Questo NON È affatto uno strumento "simile al comando temporale di Bash" . È bello sapere però ... ma: non esegue e ritorna ai<stdout> risultati del comando racchiuso tra parentesi graffe!
Kurt Pfeifle,

287

Se vuoi

  1. Per misurare il tempo di esecuzione fino al centesimo di secondo in (hh: mm: formato ss.ff)
  2. Per non dover scaricare e installare un pacchetto di risorse
  3. Per sembrare un enorme secchione DOS (che non lo fa)

Prova a copiare il seguente script in un nuovo file batch (ad esempio 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)

uso

Se inserisci timecmd.bat in una directory nel tuo percorso, puoi chiamarlo da qualsiasi luogo come questo:

timecmd [your command]

Per esempio

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

Se si desidera eseguire il reindirizzamento dell'output, è possibile citare il comando in questo modo:

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

Questo dovrebbe gestire i comandi che vengono eseguiti da prima a dopo mezzanotte, ma l'output sarà errato se il comando viene eseguito per 24 ore o più.


9
la sostituzione di cmd / c% * con % * funziona a meno che il comando non sia un altro file batch. Quindi dovresti fare timecmd call other.bat
Jesse Chisholm

2
@JesseChisholm In Windows 8 (e ho letto anche in Windows 7) non hai bisogno della chiamata per .bat
Brian J

4
Per qualche ragione, questo mi dà output solo in interi secondi ... il che per me è inutile. Voglio dire timecmd pause, corro , e risulta sempre in 1,00 secondi, 2,00 secondi, 4,00 secondi ... anche 0,00 secondi! Windows 7.
Camilo Martin,

9
@CamiloMartin e altri che avevano questo (come me) - potresti avere una localizzazione, che usa COMMA invece di DOT per i decimali. Quindi, in questo scrpit, cambia delims=:.in delims=:.,, e quindi dovrebbe funzionare "su tutta la linea".
Tomasz Gandor,

5
C'è un grave errore aritmetico in quello script: Provalo con: set start=10:10:10.10 set end=10:11:10.09E command took 0:1:-1.99 (59.99s total) genererà : Dovresti invertire l'ordine delle 4 righe che fanno confronti "lss 0", in modo che il carry proceda correttamente da cifre sessagesimali basse a alte. Quindi l'output diventa: command took 0:0:59.99 (59.99s total)
Jean-François Larvoire il

230

Hehe, la soluzione più semplice potrebbe essere questa:

echo %time%
YourApp.exe
echo %time%

Funziona su ogni Windows pronto all'uso.


Nel caso in cui un'applicazione utilizzi l'output della console, potrebbe essere utile memorizzare l'ora di inizio in una variabile temporanea:

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

163
Sei pazzo?! Ciò comporta fare matematica, come, nel tuo cervello. Ecco perché abbiamo inventato i computer, quindi abbiamo potuto evitare di fare cose del genere.
Luke Sampson,

1
brillante! Anche se, per il tempo della CPU, non aiuta davvero
Elijah Saounkine il

10
Ancora meglio (se l'app sputa l'output sulla console): set startTime=%time% \n YourApp.exe \n echo Start Time: %startTime% \n echo Finish Time: %time% (Spiacenti, non è possibile ottenere nuove righe nel commento)
Jono

1
@LukeSampson, puoi usare setper fare i conti . ;-)Oh aspetta, non importa, l'hai già fatto di seguito.
Synetech,

2
No, questa è una pessima opzione. Questo ti dice l'ora dell'orologio a muro, non l'ora della CPU. Pertanto, anche se la riga di comando potrebbe richiedere solo 100 ms, se è presente un'altra applicazione che registra la CPU, l'applicazione potrebbe richiedere alcuni secondi (disattivata di 100x o più). In effetti, se il tuo computer si sta schiantando, potresti persino aspettare un minuto per l'esecuzione della tua piccola app da 100 ms. Traccia il tempo della CPU, non l'ora del wall clock!
Ryan Shillington,

102

Solo una piccola espansione della risposta di Casey.K sull'uso di Measure-Commandda PowerShell :

  1. È possibile richiamare PowerShell dal prompt dei comandi standard, in questo modo:

    powershell -Command "Measure-Command {echo hi}"
    
  2. Questo manterrà l'output standard, ma puoi impedirlo aggiungendo | Out-Defaultcosì da PowerShell:

    Measure-Command {echo hi | Out-Default}
    

    O da un prompt dei comandi:

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

Ovviamente, sei libero di racchiuderlo in un file di script *.ps1 o *.bat.


1
Cosa succede se il comando che vogliamo misurare ha virgolette? In questo caso può essere trasformato in uno script .bat? Ad esempiomeasureTime.bat "c:\program files\some dir\program.exe"
GetFree,

53

Il one-liner che uso in Windows Server 2008 R2 è:

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

Finché mycommand non richiede virgolette (che si avvita con l'elaborazione delle virgolette di cmd). Lo scopo /v:onè consentire la valutazione indipendente dei due diversi valori TIME anziché una volta all'esecuzione del comando.


Questo non funzionerà anche per i batch di "spam", che sovrascrivono la prima volta etichetta e implica che si sostituisce il computer che esegue il calcolo, come indicato in stackoverflow.com/questions/673523/…
Val

Di solito puoi sfuggire alle citazioni ^in cmd (come ^")
n611x007

2
Se ripeti cmd / v: on per il secondo tempismo, possiamo anche fare in modo che mycommand contenga virgolette. Esempio: cmd /v:on /c echo !TIME! & echo "Quoted mycommand" & cmd /v:on /c echo !TIME!.
Maarten Pennings,

8
Più semplice: echo %time% & *mycommand* & call echo %^time%. Vedi anche questa risposta .
Aacini

Se il tuo comando emette troppo, forse è più facile mettere insieme il tempo 2:cmd /v:on /c "mycommand & echo begin=%time% endtime=!time!"
ZHANG Zikai

49

Se hai una finestra di comando aperta e chiama i comandi manualmente, puoi visualizzare un timestamp su ogni prompt, ad es

prompt $d $t $_$P$G

Ti dà qualcosa del tipo:

23.03.2009 15:45:50,77

C:\>

Se si dispone di uno script batch di piccole dimensioni che esegue i comandi, disporre di una riga vuota prima di ciascun comando, ad es

(riga vuota)

myCommand.exe

(prossima riga vuota)

myCommand2.exe

È possibile calcolare il tempo di esecuzione per ciascun comando dalle informazioni sull'ora nel prompt. Il migliore sarebbe probabilmente convogliare l'output in un file di testo per ulteriori analisi:

MyBatchFile.bat > output.txt

3
Ho pensato di abbandonare un paio di anni dietro la discussione per ringraziarti per aver condiviso il comando rapido. Ho visto molti trucchi di CMD (più di un ragazzo bash), ma questo è sfuggito alla mia attenzione.
Steve Howard,

Semplice, elegante, nessuna installazione e nessuna scrittura di file batch per un comando one shot e può cronometrare ogni fase di un file batch.
Matt,

26

Dato che altri stanno raccomandando di installare cose come freeware e PowerShell, potresti anche installare Cygwin , che ti darebbe accesso a molti comandi Unix di base come il tempo :

abe@abe-PC:~$ time sleep 5

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

Non sono sicuro di quanto sovraccarico Cygwin aggiunge.


41
Quando si risponde alle domande di Windows, Cygwin è considerato un imbroglione :-)
mivk,

14
Ha stabilito che ResourceKit, TimeMem, ptime.exe, PowerShell e altri utenti di utilità hanno iniziato a imbrogliare per primi. Pertanto, l'autore ha reso il tuo commento inappropriato prima di scriverlo.
Val

Ho anche valutato questo dato che l'ho trovata la soluzione più semplice poiché il programma gratuito Cmder include bash! cmder.net Ricorda solo che se devi fuggire dagli spazi in bash, usa una barra nera \ appena prima dello spazio, invece di "virgolette". ad es. cd / c / Program \ Files /
lukescammell

24

Non abbastanza elegante come alcune delle funzionalità su Unix, ma crea un file cmd che assomigli a:

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

Ciò visualizzerà i tempi di inizio e fine in questo modo:

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
Supponendo che non sia necessaria la portabilità in diverse lingue, è anche possibile inserire un findstr "corrente" o qualcosa del genere dopo il "tempo <nul" (buon uso del nul a proposito; ho sempre usato l'eco. | Tempo, ma non sembra così elegante :)). E usa "for" per estrarre solo il tempo, non il testo.
Joey,

2
Se le estensioni dei comandi sono abilitate (ovvero, quelle predefinite), la versione di Win XP timeha /tun'opzione che mostra solo l'ora di sistema corrente, senza che ti venga richiesto di inserire una nuova ora. Tuttavia, quando lo fai visualizza solo ore e minuti, che potrebbero non essere abbastanza buoni per alcuni usi. (Vedi la risposta di John Snow a questa domanda.)
martineau,

3
time /Tè utilizzabile solo se il processo dura diversi minuti! time < nulè più brutto ma più preciso.
PhiLho

6
Puoi anche usare quello echo %time%che fornisce lo stesso formato e precisione di time < nul, ma eviti l' Enter the new time:output ...
aschipfl

per un utilizzo indipendente dal locale e un tempo più precisowmic os get LocalDateTime
phuclv

19

Uso un software gratuito chiamato "GS Timer".

Basta creare un file batch come questo:

timer
yourapp.exe
timer /s

Se hai bisogno di una serie di orari, inserisci semplicemente l'output del timer / s in un file .txt.

Puoi scaricarlo qui: Utilità DOS gratuite di Gammadyne


La risoluzione è di 0,1 secondi.


4
Non penso che l'utilizzo di un'applicazione di terze parti possa essere considerato farlo "con mezzi standard".
martineau,

4
L'interrogatore significava "senza installare software aggiuntivo", ma poi la risposta migliore (accettata) richiede anche l'installazione di un intero Resource Kit di Windows 2003! Comunque, timer.exe era perfetto per quello che stavo solo cercando, grazie!
Hugo,

1
Questo è un link piantato. SoftPedia è una farm di clic.
Tom A

@ Tom, per favore, spiega cosa intendi per "link piantato"?
pepoluan,

10
Ecco un link diretto alla pagina dello sviluppatore: gammadyne.com/cmdline.htm#timer
Hugo

14

Sto usando Windows XP e per qualche motivo timeit.exe non funziona per me. Ho trovato un'altra alternativa: PTIME. Funziona molto bene

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

Esempio -

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

Funziona bene anche su Windows 8.1. Ho rinominato il mio in timer.exe, perché non ricordo mai il nome ptime.
Brian Burns,

11

C'è anche TimeMem (marzo 2012):

Questa è un'utilità di Windows che esegue un programma e visualizza i suoi tempi di esecuzione, l'utilizzo della memoria e le statistiche IO. È simile nella funzionalità all'utilità di tempo Unix.


10

Finché non dura più di 24 ore ...

@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
Impressionante, ma non credo che funzioni se ci sono 08 o 09 nei tempi di inizio o fine perché questi sono interpretati come ottali. La mia risposta lo gestisce :)
Luke Sampson il

6

Ecco un

Versione timer Postfix:

Esempio di utilizzo:

timeout 1 | TimeIt.cmd

Execution took  ~969 milliseconds.

Copia e incolla questo in un editor come ad esempio Notepad ++ e salvalo come 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

^ - Basato sulla versione di "Daniel Sparks"


5

Un'alternativa al tempo di misura è semplicemente "Get-Date". Non hai quella seccatura con l'output di inoltro e così via.

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

Produzione:

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

Questo è stato perfetto per me
Brett Rowberry l'

4

Questo è un one-liner che evita l'espansione ritardata , che potrebbe disturbare alcuni comandi:

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

L'output è simile a:

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

Per lungo termine prove di sostituire $Tda $D, $Te %TIME%per %DATE%, %TIME%includere la data.

Per usarlo all'interno di un file batch , sostituiscilo %Zcon %%Z.


Aggiornare

Ecco un one-liner migliorato (anche senza espansione ritardata ):

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

L'output è simile al seguente:

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

Questo approccio non include il processo di istituzione di un nuovo cmdnel risultato, né include i promptcomandi.


4

A seconda della versione di Windows che stai utilizzando, solo l'esecuzione bashti porterà in modalità Bash. Ciò consentirà di utilizzare un gruppo di comandi che non sono disponibili direttamente su PowerShell (come il timecomando). Il cronometraggio del comando è ora semplice come l'esecuzione:

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

Nota: è possibile uscire facilmente dalla modalità Bash e tornare alla shell principale eseguendo exitin modalità Bash.

Questo ha funzionato perfettamente per me (Windows 10) dopo aver provato altri metodi (come Measure-Command) che a volte producono statistiche indesiderate. Spero che questo funzioni anche per te.


2
A partire da Windows 10 1607 la migliore risposta.
CarpeDiemKopi,

2

Nel caso in cui qualcun altro sia venuto qui alla ricerca di una risposta a questa domanda, c'è una funzione API di Windows chiamata GetProcessTimes(). Non sembra troppo lavoro per scrivere un piccolo programma C che avvierebbe il comando, effettuasse questa chiamata e restituisse i tempi di processo.


3
Non sembra troppo lavoro per scaricare un piccolo programma in C che avvierebbe il comando, fare questa chiamata (e molto più misure anticipate) e restituire i tempi di processo.
Elazar Leibovich,

@ElazarLeibovich powershell? Puoi chiamarlo da C #.
KeyWeeUsr

@KeyWeeUsr è possibile utilizzare Windows API IIRC da PS blogs.technet.microsoft.com/heyscriptingguy/2013/06/25/…
Elazar Leibovich,

2

Questo è un commento / modifica per il simpatico timecmd.bate la risposta di Luke Sampson

Per qualche ragione, questo mi dà output in pochi secondi ... il che per me è inutile. Voglio dire che eseguo pausa timecmd, e risulta sempre in 1,00 secondi, 2,00 secondi, 4,00 secondi ... anche 0,00 secondi! Windows 7. - Camilo Martin, 25 settembre 13 alle 16:00 "

In alcune configurazioni i delimitatori possono differire. La seguente modifica dovrebbe riguardare almeno la maggior parte dei paesi occidentali.

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

Il %time% millisecondi funzionano sul mio sistema dopo aver aggiunto ','

(* perché il sito non consente commenti anonimi e non tiene traccia dell'identità, anche se utilizzo sempre la stessa e-mail ospite che, combinata con ipv6 ip e impronta digitale del browser, dovrebbe essere sufficiente per identificare in modo univoco senza password)


Ho commentato solo questo prima di scorrere verso il basso fino alla tua risposta. Comunque, la sceneggiatura di Luke potrebbe azzerare ore, minuti e secondi, non solo i secondi (che sono centisecondi e non millisecondi, BTW). Vedi qui: en.wiktionary.org/wiki/centisecond
Tomasz Gandor

2

Ecco il mio metodo, nessuna conversione e nessun ms. È utile determinare la durata della codifica (limitata a 24 ore):

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

Non funziona. Ottenere: parentesi sbilanciata. Parentesi sbilanciata. Operando mancante.
Richard Sandoz,

@RichardSandoz Funziona bene, non ci sono parentesi sbilanciate. Come lo stai usando?
MikeM,

1

Lo script seguente utilizza solo "cmd.exe" e genera il numero di millisecondi dal momento in cui viene creata una pipeline al momento in cui termina il processo che precede lo script. ad esempio, digitare il comando e reindirizzare allo script. Esempio: "timeout 3 | runtime.cmd" dovrebbe produrre qualcosa come "2990." Se hai bisogno sia dell'output di runtime sia dell'output stdin, reindirizza stdin prima del pipe - es: "dir / s 1> temp.txt | runtime.cmd" scarica l'output del comando "dir" su "temp.txt" e stamperebbe il runtime sulla 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

Bene, invece di chiamare ricorsivamente la sceneggiatura, considera di farlo in questo modo call :calc. L'ho fatto qui. link Code get è qualcosa di più bello in questo modo. : D
Nadu,

Bug n. 1 fallirà alla dodicesima ora. Esempio: " 0 : 23: 19,42" Errore n. 2 non riuscirà se il punto decimale è diverso da. stesso esempio: "0:23:19 , 42" qui è il punto decimale, <__________> Ben provato a modificare tuttavia quel muto **** nella "commissione di approvazione modifica" lo ha respinto - 3 su 5 votato "Anche questa modifica cambia gran parte dell'intento originale degli autori ". quindi se hai voglia di tentare la fortuna modificando o semplicemente mantieni i bug dentro - così l'intento originale degli autori rimane intatto. facepalm
Nadu,

Impossibile emettere millisecondi quando la risoluzione del tuo orologio è a malapena in grado di raggiungere una risoluzione di 1/100 di secondo.
jwdonahue,

1

La risposta di driblio può essere resa un po 'più breve (anche se non molto leggibile)

@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

Per l' osservazione di Luke Sampson questa versione è assolutamente sicura, sebbene l'attività dovrebbe essere completata in 24 ore.


Non funziona. Operatore mancante all'ora a una cifra.
Richard Sandoz

set _time=%time: =0% risolve il problema relativo all'ora a una cifra: sostituire in entrambi i punti.
Laur

1
  1. Nella directory in cui si trova il programma, digitare notepad mytimer.bat, fare clic su "Sì" per creare un nuovo file.

  2. Incolla il codice qui sotto, sostituendolo YourApp.execon il tuo programma, quindi salva.

    @echo off
    date /t
    time /t
    YourApp.exe
    date /t
    time /t
  3. Digita mytimer.batla riga di comando, quindi premi Invio.


7
time / t ti dà solo il tempo in HH: MM. Per cronometrare un eseguibile, di solito hai bisogno di più precisione ... È qualcosa che puoi impostare per arrivare a frazioni di secondo? Ho testato il sollution di JohnW (tempo <nul), e questo in realtà dà il tempo a 1/100: HH: MM: SS.XX
timore

1

il mio codice ti dà il tempo di esecuzione in millisecondi, fino a 24 ore, non è sensibile alle impostazioni locali e tiene conto dei valori negativi se il codice scorre per mezzanotte. usa l'espansione ritardata e dovrebbe essere salvata in un file cmd / bat.

prima del tuo codice:

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%

dopo il tuo codice:

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

se vuoi un tempo di esecuzione in formato HH: mm: ss.000, aggiungi:

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

La variabile t2mantiene il tempo di esecuzione, è possibile echo %t2%visualizzarlo.


1

Dopo aver installato Perl la soluzione di assunzioni disponibile, eseguire:

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

STDERR viene prima dei secondi misurati

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

Utilizzo di un sub per restituire il tempo in centesimi di secondo

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

TIMER "Lean and Mean" con formato regionale, 24 ore e supporto input misto
Adattamento di Aacini corpo del metodo di sostituzione , nessun IF, solo un FOR (la mia correzione regionale)

1: File timer.bat posizionato da qualche parte in% PATH% o nella directory corrente

@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

Utilizzo:
timer & echo start_cmds e timeout / t 3 e echo end_cmds e timer
timer e 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 fino a mezzanotte =! Timer_end!
L'input ora può essere miscelato, per quelli improbabili, ma possibili cambi di formato dell'ora durante l'esecuzione

2: Funzione : timer in bundle con lo script batch (utilizzo di esempio di seguito):

@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

:: per testarlo, copia e incolla le sezioni di codice sopra e sotto

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 e CS, supporto DS per estremità dei due punti, estremità dei punti e due punti, set di punti - utilizzato per il supporto di formati misti


0

Il seguente script emula il tempo di epoca * nix, ma è locale e regionale. Dovrebbe gestire i casi del bordo del calendario compreso gli anni bisestili. Se Cygwin è disponibile, i valori di epoca possono essere confrontati specificando l' opzione Cygwin .

Sono in EST e la differenza segnalata è di 4 ore, il che è relativamente corretto. Ci sono alcune soluzioni interessanti per rimuovere la TZ e le dipendenze regionali, ma nulla di banale che ho notato.

@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

Curioso del downvote. Grazie.
bvj,

0

Una soluzione che utilizza PHP puro per cmd e un env. variabile:

@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');"
  • nessuna necessità di cygwin o utility non attendibili. Utile quando PHP è disponibile localmente

  • la precisione e il formato di output possono essere facilmente modificati

  • la stessa idea può essere trasferita per PowerShell

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.