Comment mesurer le temps d'exécution d'une commande sur la ligne de commande Windows?


Réponses:


113

Si vous utilisez Windows 2003 (notez que Windows Server 2008 et versions ultérieures ne sont pas prises en charge), vous pouvez utiliser le Kit de ressources Windows Server 2003, qui contient timeit.exe qui affiche des statistiques d'exécution détaillées. Voici un exemple, chronométrant la commande "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

Vous pouvez obtenir TimeIt dans le Kit de ressources Windows 2003. Téléchargez-le ici .


7
Ce kit a des problèmes avec Windows 2008 64 bits et ne fonctionne pas sur 2008 R2
Artem

Existe-t-il un moyen de mesurer également le temps du noyau et / ou le temps utilisé par les sous-processus générés?
rogerdpack

38
Pour info - je ne pense pas que timeit fonctionne sur Windows 7 64 bits. Vous obtenez l'erreur «Impossible d'interroger les données de performances du système (c0000004). À la place, utilisez la« mesure-commande »de PowerShell comme Casey.K suggère: stackoverflow.com/questions/673523/…
Michael La Voie

6
Dans Windows 7, je vois "" timeit "n'est pas reconnu comme une commande interne ou externe, un programme exploitable ou un fichier de commandes."
Colonel Panic

3
Je ne vois pas la commande dans Windows 10 et je ne trouve pas facilement un Kit de ressources pour Win 10. Est-ce que quelqu'un sait comment l'obtenir pour 10?
Jay Imerman

469

Alternativement, Windows PowerShell a une commande intégrée qui est similaire à la commande "time" de Bash. Cela s'appelle "Mesure-Commande". Vous devrez vous assurer que PowerShell est installé sur la machine qui l'exécute.

Exemple d'entrée:

Measure-Command {echo hi}

Exemple de sortie:

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
Ceci est la meilleure solution pour les utilisateurs de Windows 7 car timeit.exe ne semble pas prendre en charge Windows 7
Michael La Voie

14
Dans le cas où vous souhaitez utiliser des commandes internes de dos (par exemple: dir, echo, del, etc.), n'oubliez pas d'insérer "cmd / c": Measure-Command {cmd / c dir / sc: \ windows> nul}
LietKynes

7
Si vous évaluez la performance d' un .exedans le répertoire courant, utilisez: Measure-Command { .\your.exe }. PowerShell n'exécute apparemment pas les choses à pwdmoins d'y être explicitement invité.
Cristian Diaconescu

13
De façon ennuyeuse, il cache cependant l'étalon.
Zitrax

13
Ce n'est PAS DU TOUT un outil "similaire à la commande de temps de Bash" . C'est bien de savoir quand même ... mais: il ne s'exécute pas et ne renvoie pas<stdout> aux résultats de la commande entre crochets!
Kurt Pfeifle

287

Si tu veux

  1. Pour mesurer le temps d'exécution jusqu'au centième de seconde en (format hh: mm: ss.ff)
  2. Pour ne pas avoir à télécharger et installer un pack de ressources
  3. Pour ressembler à un énorme nerd DOS (qui ne le fait pas)

Essayez de copier le script suivant dans un nouveau fichier de commandes (par exemple 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)

Usage

Si vous placez timecmd.bat dans un répertoire de votre chemin, vous pouvez l'appeler de n'importe où comme ceci:

timecmd [your command]

Par exemple

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

Si vous voulez faire une redirection de sortie, vous pouvez citer la commande comme ceci:

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

Cela devrait gérer les commandes qui s'exécutent avant-après minuit, mais la sortie sera incorrecte si votre commande s'exécute pendant 24 heures ou plus.


9
remplacer cmd / c% * par % * fonctionne sauf si votre commande est un autre fichier batch. Ensuite, vous devez faire timecmd appeler other.bat
Jesse Chisholm

2
@JesseChisholm Dans Windows 8 (et j'ai également lu dans Windows 7), vous n'avez pas besoin de l'appel pour .bat
Brian J

4
Pour une raison quelconque, cela ne me donne une sortie qu'en secondes entières ... ce qui pour moi est inutile. Je veux dire que je cours timecmd pause, et cela se traduit toujours par 1,00 sec, 2,00 sec, 4,00 sec ... même 0,00 sec! Windows 7.
Camilo Martin

9
@CamiloMartin et d'autres qui l'ont eu (comme moi) - vous pouvez avoir une locale, qui utilise COMMA au lieu de DOT pour la décimale. Donc, dans ce scrpit, passez delims=:.à delims=:.,, et ensuite cela devrait fonctionner "à tous les niveaux".
Tomasz Gandor

5
Il y a une grave erreur arithmétique dans ce script: Essayez-le avec: set start=10:10:10.10 set end=10:11:10.09Et il produira: command took 0:1:-1.99 (59.99s total) Vous devez inverser l'ordre des 4 lignes qui font des comparaisons "lss 0", de sorte que le report progresse correctement des chiffres sexagésimaux bas à haut. La sortie devient alors: command took 0:0:59.99 (59.99s total)
Jean-François Larvoire

230

Hehe, la solution la plus simple pourrait être la suivante:

echo %time%
YourApp.exe
echo %time%

Cela fonctionne sur toutes les fenêtres prêtes à l'emploi.


Dans le cas d'une application utilisant la sortie console, il peut être pratique de stocker l'heure de début dans une variable temporaire:

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

163
Êtes-vous fou?! Cela implique de faire des calculs dans votre cerveau. C'est pourquoi nous avons inventé les ordinateurs, pour éviter de faire des trucs comme ça.
Luke Sampson

1
brillant! Même si, pour le temps CPU, cela n'aide pas vraiment
Elijah Saounkine

10
Encore mieux (si votre application crache la sortie sur la console): set startTime=%time% \n YourApp.exe \n echo Start Time: %startTime% \n echo Finish Time: %time% (Désolé, impossible d'obtenir des retours à la ligne dans le commentaire)
Jono

1
@LukeSampson, vous pouvez utiliser setpour faire le calcul. ;-)Oh attends, peu importe, tu l'as déjà fait ci-dessous.
Synetech

2
Non, c'est une mauvaise option. Cela vous indique l'heure de l'horloge murale, pas l'heure du processeur. Ainsi, même si votre ligne de commande peut ne prendre que 100 ms, s'il existe une autre application monopolisant le processeur, votre application peut prendre quelques secondes (au moins 100 fois). En fait, si votre machine se débat, vous pouvez même attendre une minute pour que votre petite application de 100 ms s'exécute. Suivez le temps CPU, pas le temps de l'horloge murale!
Ryan Shillington

102

Juste une petite extension de la réponse de Casey.K à propos de l'utilisation Measure-Commandde PowerShell :

  1. Vous pouvez appeler PowerShell à partir de l'invite de commande standard, comme ceci:

    powershell -Command "Measure-Command {echo hi}"
    
  2. Cela mangera la sortie standard, mais vous pouvez empêcher cela en ajoutant | Out-Defaultcomme ceci à partir de PowerShell:

    Measure-Command {echo hi | Out-Default}
    

    Ou à partir d'une invite de commande:

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

Bien sûr, vous êtes libre de l'envelopper dans un fichier script *.ps1ou *.bat.


1
Et si la commande que nous voulons mesurer a des guillemets? Peut-il être transformé en un script .bat dans ce cas? Par exemplemeasureTime.bat "c:\program files\some dir\program.exe"
GetFree

53

Le one-liner que j'utilise dans Windows Server 2008 R2 est:

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

Tant que ma commande ne nécessite pas de guillemets (qui se visse avec le traitement des devis de cmd). Il /v:ons'agit de permettre aux deux valeurs TIME différentes d'être évaluées indépendamment plutôt qu'une fois lors de l'exécution de la commande.


Cela ne fonctionnera pas non plus pour les lots de "spam", qui écrasent la première étiquette de temps et impliquent que vous remplaciez l'ordinateur effectuant le calcul, comme indiqué dans stackoverflow.com/questions/673523/…
Val

Habituellement, vous pouvez échapper aux citations ^en cmd (comme ^")
n611x007

2
Si vous répétez la commande cmd / v: on pour la deuxième synchronisation, nous pouvons même avoir ma commande contenant des guillemets. Exemple: cmd /v:on /c echo !TIME! & echo "Quoted mycommand" & cmd /v:on /c echo !TIME!.
Maarten Pennings

8
Simple: echo %time% & *mycommand* & call echo %^time%. Voir aussi cette réponse .
Aacini

Si votre commande sort trop, c'est peut-être plus facile de simplement mettre les 2 temps ensemble:cmd /v:on /c "mycommand & echo begin=%time% endtime=!time!"
ZHANG Zikai

49

Si une fenêtre de commande est ouverte et appelle les commandes manuellement, vous pouvez afficher un horodatage à chaque invite, par exemple

prompt $d $t $_$P$G

Cela vous donne quelque chose comme:

23.03.2009 15:45:50,77

C:\>

Si vous avez un petit script batch qui exécute vos commandes, ayez une ligne vide avant chaque commande, par exemple

(ligne vide)

myCommand.exe

(ligne vide suivante)

myCommand2.exe

Vous pouvez calculer le temps d'exécution pour chaque commande en fonction des informations de temps dans l'invite. Le mieux serait probablement de diriger la sortie vers un fichier texte pour une analyse plus approfondie:

MyBatchFile.bat > output.txt

3
Je pensais que je laisserais tomber quelques années derrière la discussion pour vous remercier d'avoir partagé la commande rapide. J'ai vu beaucoup de trucs CMD (plus d'un gars bash), mais celui-ci a échappé à mon attention.
Steve Howard

Simple, élégant, aucune installation et aucune écriture de fichiers batch pour une commande one shot et peut chronométrer chaque étape dans un fichier batch.
Matt

26

Étant donné que d'autres recommandent d'installer des choses comme les logiciels gratuits et PowerShell, vous pouvez également installer Cygwin , ce qui vous donnerait accès à de nombreuses commandes Unix de base comme le temps :

abe@abe-PC:~$ time sleep 5

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

Je ne sais pas combien de frais généraux Cygwin ajoute.


41
En répondant aux questions de Windows, Cygwin est considéré comme de la triche :-)
mivk

14
Il a stipulé que ResourceKit, TimeMem, ptime.exe, PowerShell et d'autres utilisateurs d'utilitaires ont commencé à tricher en premier. Par conséquent, l'auteur a rendu votre commentaire inapproprié avant de l'écrire.
Val

J'ai également voté pour cela depuis que je l'ai trouvé la solution la plus simple puisque le programme gratuit Cmder inclut bash! cmder.net N'oubliez pas que si vous avez besoin d'échapper aux espaces dans bash, utilisez une barre oblique noire \ juste avant l'espace, au lieu de "guillemets". par exemple, cd / c / Program \ Files /
lukescammell

24

Pas aussi élégant que certaines des fonctionnalités d'Unix, mais créez un fichier cmd qui ressemble à:

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

Cela affichera les heures de début et de fin comme suit:

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
En supposant que vous n'avez pas besoin de portabilité dans différentes langues, vous pouvez également mettre un findstr "courant" ou quelque chose comme ça après le "time <nul" (belle utilisation de nul au fait; j'ai toujours utilisé echo. | Time, mais ça n'a pas l'air aussi élégant :)). Et utilisez "pour" pour extraire uniquement l'heure, pas le texte.
Joey

2
Si les extensions de commande sont activées (c'est-à-dire la valeur par défaut), la version Win XP de timepossède une /toption qui affiche simplement l'heure actuelle du système, sans vous inviter à entrer une nouvelle heure. Cependant, lorsque vous faites cela, il n'affiche que les heures et les minutes, ce qui peut ne pas être suffisant pour certaines utilisations. (Voir la réponse de John Snow à cette question.)
martineau

3
time /Tn'est utilisable que si le processus dure plusieurs minutes! time < nulest plus laid mais plus précis.
PhiLho

6
Vous pouvez également utiliser echo %time%ce qui fournit le même format et la même précision que time < nul, mais vous évitez la Enter the new time:sortie ...
aschipfl

pour une utilisation du temps plus précise et indépendante du lieuwmic os get LocalDateTime
phuclv

19

J'utilise un logiciel gratuit appelé "GS Timer".

Créez simplement un fichier batch comme celui-ci:

timer
yourapp.exe
timer /s

Si vous avez besoin d'un ensemble d'heures, dirigez simplement la sortie de timer / s dans un fichier .txt.

Vous pouvez l'obtenir ici: Les utilitaires DOS gratuits de Gammadyne


La résolution est de 0,1 seconde.


4
Je ne pense pas que l'utilisation d'une application tierce puisse être envisagée "avec des moyens standard".
martineau

4
L'interrogateur voulait dire "sans installer de logiciel supplémentaire", mais la réponse du haut (acceptée) nécessite également l'installation d'un kit de ressources Windows 2003 complet! Quoi qu'il en soit, timer.exe était parfait pour ce que je cherchais, merci!
Hugo

1
Ceci est un lien planté. SoftPedia est une ferme de clics.
Tom A

@ Tom, veuillez expliquer, que voulez-vous dire par "lien planté"?
pepoluan

10
Voici un lien direct vers la page du développeur: gammadyne.com/cmdline.htm#timer
Hugo

14

J'utilise Windows XP et pour une raison quelconque, timeit.exe ne fonctionne pas pour moi. J'ai trouvé une autre alternative - PTIME. Cela fonctionne très bien.

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

Exemple -

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

Fonctionne également bien sur Windows 8.1. J'ai renommé le mien en timer.exe, car je ne me souviens jamais du nom ptime.
Brian Burns

11

Il y a aussi TimeMem (mars 2012):

Il s'agit d'un utilitaire Windows qui exécute un programme et affiche son temps d'exécution, l'utilisation de la mémoire et les statistiques d'E / S. Sa fonctionnalité est similaire à l'utilitaire de temps Unix.


10

Tant qu'il ne dure pas plus de 24h ...

@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
Impressionnant, mais je ne pense pas que cela fonctionne s'il y a un 08 ou 09 dans les heures de début ou de fin car elles sont interprétées comme des octales. Ma réponse gère cela :)
Luke Sampson

6

Voici une

Version du temporisateur Postfix:

Exemple d'utilisation:

délai d'expiration 1 | TimeIt.cmd

Execution took  ~969 milliseconds.

Copiez et collez ceci dans un éditeur comme par exemple Notepad ++ et enregistrez-le sous 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

^ - Basé sur la version de «Daniel Sparks»


5

Une alternative à la mesure du temps est simplement "Get-Date". Vous n'avez pas ce tracas avec la sortie de transfert et ainsi de suite.

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

Production:

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

C'était parfait pour moi
Brett Rowberry

4

Il s'agit d'un monocylindre qui évite une expansion retardée , ce qui pourrait perturber certaines commandes:

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

La sortie est quelque chose comme:

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

Pour les tests à long terme, remplacer $Tpar $D, $Tet %TIME%par %DATE%, %TIME%pour inclure la date.

Pour l'utiliser à l'intérieur d'un fichier de commandes , remplacez %Zpar %%Z.


Mise à jour

Voici une doublure améliorée (sans expansion retardée aussi):

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

La sortie ressemble à ceci:

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

Cette approche n'inclut pas le processus d'instanciation d'une nouvelle cmddans le résultat, ni la ou les promptcommandes.


4

Selon la version de Windows que vous utilisez, une simple exécution bashvous mettra en mode Bash. Cela vous permettra d'utiliser un tas de commandes qui ne sont pas disponibles directement sur PowerShell (comme la timecommande). Le chronométrage de votre commande est désormais aussi simple que l'exécution:

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

Remarque: Vous pouvez facilement quitter le mode Bash et revenir dans votre shell principal en exécutant exiten mode Bash.

Cela a fonctionné parfaitement pour moi (Windows 10) après avoir essayé d'autres méthodes (comme Measure-Command) qui produisent parfois des statistiques indésirables. J'espère que cela fonctionne aussi pour vous.


2
Depuis Windows 10 1607, la meilleure réponse.
CarpeDiemKopi

2

Au cas où quelqu'un d'autre serait venu ici à la recherche d'une réponse à cette question, il existe une fonction API Windows appelée GetProcessTimes(). Il ne ressemble pas à trop de travail pour écrire un petit programme C qui démarrerait la commande, ferait cet appel et renverrait les temps de traitement.


3
Il ne semble pas trop de travail de télécharger un petit programme C qui démarrerait la commande, ferait cet appel (et beaucoup plus de mesures avancées) et renverrait les temps de traitement.
Elazar Leibovich

@ElazarLeibovich powershell? Vous pouvez l'appeler à partir de C #.
KeyWeeUsr

@KeyWeeUsr, vous pouvez utiliser Windows API IIRC sur PS blogs.technet.microsoft.com/heyscriptingguy/2013/06/25/…
Elazar Leibovich

2

Ceci est un commentaire / éditer à gentil de Luke Sampson timecmd.batet répondre à

Pour une raison quelconque, cela ne me donne une sortie qu'en secondes entières ... ce qui pour moi est inutile. Je veux dire que je lance une pause timecmd, et cela se traduit toujours par 1,00 sec, 2,00 sec, 4,00 sec ... même 0,00 sec! Windows 7. - Camilo Martin 25 sept. 13 à 16:00 "

Sur certaines configurations, les délimiteurs peuvent différer. Le changement suivant devrait couvrir au moins la plupart des pays occidentaux.

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

Les %time%millisecondes fonctionnent sur mon système après avoir ajouté que ","

(* parce que le site n'autorise pas les commentaires anon et ne garde pas une bonne trace d'identité même si j'utilise toujours le même e-mail d'invité qui, combiné à l'ip ip6 et à l'empreinte digitale du navigateur, devrait être suffisant pour s'identifier de manière unique sans mot de passe)


Je l'ai juste commenté avant de défiler jusqu'à votre réponse. Quoi qu'il en soit, le script de Luke pourrait mettre à zéro les heures, les minutes et les secondes, pas seulement les sous-secondes (qui sont des centisecondes et non des millisecondes, BTW). Voir ici: en.wiktionary.org/wiki/centisecond
Tomasz Gandor

2

Voici ma méthode, pas de conversion et pas de ms. Il est utile de déterminer les durées d'encodage (limitées à 24 heures cependant):

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

Ne marche pas. Obtention: parenthèse déséquilibrée. Parenthèse déséquilibrée. Opérande manquant.
Richard Sandoz

@RichardSandoz Cela fonctionne bien, il n'y a pas de parenthèses déséquilibrées. Comment l'utilisez-vous?
MikeM

1

Le script suivant utilise uniquement "cmd.exe" et génère le nombre de millisecondes entre la création d'un pipeline et la fin du processus précédant le script. c'est-à-dire, tapez votre commande et dirigez-la vers le script. Exemple: "timeout 3 | runtime.cmd" devrait produire quelque chose comme "2990". Si vous avez besoin à la fois de la sortie d'exécution et de la sortie stdin, redirigez stdin avant le canal - ex: "dir / s 1> temp.txt | runtime.cmd" viderait la sortie de la commande "dir" vers "temp.txt" et imprimerait le runtime sur la 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

Eh bien, au lieu d' appeler récursivement le script, envisagez de le faire comme ceci call :calc. Je l'ai fait ici. Le code de lien est plus agréable de cette façon. : D
Nadu

Le bogue # 1 échouera à la 12e heure. Exemple: " 0 : 23: 19,42" Bogue n ° 2 Échouera si le point décimal est autre chose que. même exemple: "0:23:19 , 42" ici le point décimal est, <__________> Bien essayé de modifier cependant ce stupide **** de la "commission d'approbation de modification" l'a rejeté - 3 sur 5 ont voté "Cette modification change aussi une grande partie de l'intention originale des auteurs. " Donc, si vous avez envie de tenter votre chance de modifier ou de simplement garder les bogues - de sorte que «l'intention originale des auteurs reste intacte». facepalm
Nadu

Impossible de produire des millisecondes lorsque la résolution de votre horloge est à peine capable d'une résolution de 1/100 seconde.
jwdonahue

1

La réponse de driblio peut être un peu plus courte (mais pas très lisible)

@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

À la remarque de Luke Sampson, cette version est sans danger octal, bien que la tâche devrait être terminée en 24 heures.


Ne marche pas. Opérateur manquant lorsque l'heure à un chiffre.
Richard Sandoz

set _time=%time: =0%résout le problème de l'heure à un chiffre - remplacez-le aux deux endroits.
Laur

1
  1. Dans le répertoire où se trouve votre programme, tapez notepad mytimer.bat, cliquez sur 'oui' pour créer un nouveau fichier.

  2. Collez le code ci-dessous, en le remplaçant YourApp.exepar votre programme, puis enregistrez.

    @echo off
    date /t
    time /t
    YourApp.exe
    date /t
    time /t
  3. Saisissez mytimer.batla ligne de commande, puis appuyez sur Entrée.


7
time / t vous donne uniquement du temps en HH: MM. Pour chronométrer un exécutable, vous avez généralement besoin de plus de précision ... Est-ce quelque chose que vous pouvez configurer pour descendre à des fractions de seconde? J'ai testé la sollicution de JohnW (time <nul), et cela donne en fait le temps jusqu'à 1 / 100s: HH: MM: SS.XX
awe

1

mon code vous donne le temps d'exécution en millisecondes, jusqu'à 24 heures, il est insensible aux paramètres régionaux et tient compte des valeurs négatives si le code s'exécute jusqu'à minuit. il utilise une expansion retardée et doit être enregistré dans un fichier cmd / bat.

avant votre code:

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%

après votre code:

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

si vous voulez un temps d'exécution au format HH: mm: ss.000, ajoutez:

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

variable t2détient votre temps de course, vous pouvez l' echo %t2%afficher.


1

Une fois que Perl a installé la solution d'embauche disponible, exécutez:

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

STDERR vient avant les secondes mesurées

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

Utilisation d'un sous-marin pour renvoyer le temps en centièmes de seconde

::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" avec format régional, prise en charge 24h et entrées mixtes
Adaptation du corps de la méthode de substitution d'Aacini , pas de IF, juste un FOR (mon correctif régional)

1: fichier timer.bat placé quelque part dans% PATH% ou le répertoire courant

@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

Utilisation:
timer & echo start_cmds & timeout / t 3 & echo end_cmds & timer
timer & timer "23: 23: 23,00"
timer "23: 23: 23,00" & timer
timer "13.23.23,00" & timer "03: 03: 03.00"
timer & timer "0: 00: 00.00" no & cmd / v: on / c écho jusqu'à minuit =! Timer_end!
L'entrée peut maintenant être mélangée, pour ceux peu probables, mais les changements de format d'heure possibles pendant l'exécution

2: Fonction : minuterie fournie avec le script batch (exemple d'utilisation ci-dessous):

@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

:: pour le tester, copiez-collez les sections de code au-dessus et en dessous

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 et CS, DS signifient deux-points, un point et un ensemble de points, un ensemble de points - utilisé pour la prise en charge de formats mixtes


0

Le script suivant émule * nix epoch time, mais il est local et régional. Il devrait gérer les cas de bord de calendrier, y compris les années bissextiles. Si Cygwin est disponible, les valeurs d'époque peuvent être comparées en spécifiant l' option Cygwin .

Je suis en EST et la différence signalée est de 4 heures, ce qui est relativement correct. Il existe des solutions intéressantes pour supprimer les dépendances TZ et régionales, mais rien de trivial que j'ai remarqué.

@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

Curieux de connaître le downvote. Merci.
bvj

0

Une solution utilisant du PHP pur pour cmd et un env. variable:

@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');"
  • pas besoin de cygwin ou d'utilitaires non fiables. Utile lorsque PHP est disponible localement

  • la précision et le format de sortie peuvent être facilement modifiés

  • la même idée peut être portée pour PowerShell

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.