Как измерить время выполнения команды в командной строке Windows?


Ответы:


113

Если вы используете Windows 2003 (обратите внимание, что Windows Server 2008 и более поздние версии не поддерживаются), вы можете использовать Windows Server 2003 Resource Kit, который содержит timeit.exe, который отображает подробную статистику выполнения. Вот пример времени команды «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

Вы можете получить TimeIt в Windows 2003 Resource Kit. Загрузите это здесь .


7
Этот комплект имеет проблемы с Windows 2008 64bit и не работает на 2008 R2
Артем

Есть ли способ также измерить время ядра и / или время, используемое подпроцессами?
rogerdpack

38
К вашему сведению - я не думаю, что timeit работает на Windows 7 64-bit. Появляется ошибка «Невозможно запросить данные о производительности системы (c0000004). Вместо этого используйте« Measure-Command »PowerShell, как предлагает Кейси.K: stackoverflow.com/questions/673523/…
Michael La Voie

6
В Windows 7 я вижу «timeit» не распознается как внутренняя или внешняя команда, работающая программа или пакетный файл ».
полковник Паник

3
Я не вижу команды в Windows 10, и при этом я не могу легко найти Resource Kit для Win 10. Кто-нибудь знает, как получить это для 10?
Джей Имерман

469

В качестве альтернативы, в Windows PowerShell есть встроенная команда, которая похожа на команду времени Bash. Это называется «Мера-Команда». Вы должны убедиться, что PowerShell установлен на компьютере, на котором он запущен.

Пример ввода:

Measure-Command {echo hi}

Пример вывода:

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
Это лучшее решение для пользователей Windows 7, так как timeit.exe не поддерживает Windows 7
Michael La Voie

14
Если вы хотите использовать внутренние команды dos (например: dir, echo, del и т. Д.), Не забудьте вставить «cmd / c»: Measure-Command {cmd / c dir / sc: \ windows> nul}
LietKynes

7
Если вы бенчмаркинга .exeв текущем каталоге, используйте это: Measure-Command { .\your.exe }. PowerShell, очевидно, не запускает что-либо, pwdесли явно не указано иное.
Кристиан Диаконеску

13
Досадно, что скрывает стандартный вывод.
Цитракс

13
Это вовсе не инструмент, «похожий на команду времени Bash» . Хотя это приятно знать ... но: он не выполняется и не возвращает<stdout> результаты команды, заключенной в фигурные скобки!
Курт Пфайфл

287

Если хочешь

  1. Чтобы измерить время выполнения с точностью до сотой секунды в формате (чч: мм: сс.фф)
  2. Чтобы не пришлось скачивать и устанавливать пакет ресурсов
  3. Чтобы выглядеть как огромный ботаник DOS (кто не)

Попробуйте скопировать следующий скрипт в новый пакетный файл (например, 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)

Применение

Если вы поместите timecmd.bat в каталог вашего пути, вы можете вызвать его из любого места, например:

timecmd [your command]

Например

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

Если вы хотите сделать перенаправление вывода, вы можете заключить команду в кавычки так:

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

Это должно обрабатывать команды, которые выполняются до - после полуночи, но вывод будет неправильным, если ваша команда выполняется в течение 24 часов или более.


9
замена cmd / c% * на % * работает, если ваша команда не является другим командным файлом. Тогда вам нужно будет сделать timecmd call other.bat
Джесси Чисхолм

2
@JesseChisholm В Windows 8 (и я также читал в Windows 7) вам не нужен вызов для .bat
Брайан Дж

4
По какой-то причине это дает мне вывод только в целых секундах ... что для меня бесполезно. Я имею в виду, что я бегу timecmd pause, и это всегда приводит к 1,00 с, 2,00 с, 4,00 с ... даже к 0,00 с! Windows 7.
Камило Мартин,

9
@CamiloMartin и другие, у которых это было (например, я) - у вас может быть языковой стандарт, в котором для десятичной дроби используется COMMA вместо DOT. Итак, в этом scrpit измените delims=:.на delims=:.,, и тогда он должен работать "по всем направлениям".
Томаш Гандор

5
В этом сценарии есть серьезная арифметическая ошибка: попробуйте с: set start=10:10:10.10 set end=10:11:10.09И он выведет: command took 0:1:-1.99 (59.99s total) Вы должны изменить порядок 4 строк, которые выполняют сравнения «lss 0», чтобы перенос переносился правильно от младших к старшим разрядам. Затем вывод становится: command took 0:0:59.99 (59.99s total)
Жан-Франсуа Ларвуар

230

Хе-хе, самое простое решение может быть таким:

echo %time%
YourApp.exe
echo %time%

Это работает на каждой Windows из коробки.


В случае приложения, использующего вывод консоли, может быть удобно сохранить время запуска во временной переменной:

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

163
Ты не в своем уме?! Это подразумевает выполнение математики в вашем мозгу. Вот почему мы изобрели компьютеры, чтобы избежать подобных вещей.
Люк Сэмпсон

1
блестящий! Хотя для процессорного времени это не очень помогает
Элайджа Саункин

10
Еще лучше (если ваше приложение выплевывает вывод на консоль): set startTime=%time% \n YourApp.exe \n echo Start Time: %startTime% \n echo Finish Time: %time% (Извините, не удалось получить переводы строк в комментарии)
Jono

1
@ LukeSampson, вы можете использовать, setчтобы сделать математику. ;-)Ой, подождите, неважно, вы уже сделали это ниже.
Synetech

2
Нет, это плохой вариант. Это говорит о времени настенных часов, а не о времени процессора. Таким образом, даже если ваша командная строка может занять всего 100 мс, если есть другое приложение, загружающее ЦП, ваше приложение может занять несколько секунд (в 100 раз или больше). На самом деле, если ваша машина работает, вы можете даже подождать минуту, пока ваше маленькое приложение на 100 мс запустится. Отслеживайте время процессора, а не время настенных часов!
Райан Шиллингтон

102

Просто немного расширения ответа от Casey.K об использовании Measure-Commandс помощью PowerShell :

  1. Вы можете вызвать PowerShell из стандартной командной строки, например:

    powershell -Command "Measure-Command {echo hi}"
    
  2. Это будет использовать стандартный вывод, но вы можете предотвратить это, добавив | Out-Defaultвот что из PowerShell:

    Measure-Command {echo hi | Out-Default}
    

    Или из командной строки:

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

Конечно, вы можете обернуть это в файл сценария *.ps1или *.bat.


1
Что если команда, которую мы хотим измерить, имеет кавычки? Может ли это быть превращено в сценарий .bat в этом случае? НапримерmeasureTime.bat "c:\program files\some dir\program.exe"
GetFree

53

Однострочник, который я использую в Windows Server 2008 R2:

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

До тех пор, пока mycommand не требует кавычек (какие винты с обработкой кавычек cmd). Это /v:onделается для того, чтобы два разных значения ВРЕМЕНИ оценивались независимо, а не один раз при выполнении команды.


Это также не будет работать для пакетов «спам», которые перезаписывают метку первого времени и подразумевают, что вы заменяете компьютер, выполняющий вычисления, как отмечено в stackoverflow.com/questions/673523/…
Val

Обычно вы можете избежать кавычек ^в cmd (например ^")
n611x007

2
Если вы повторите команду cmd / v: on во второй раз, мы даже можем иметь mycommand, содержащий кавычки. Пример: cmd /v:on /c echo !TIME! & echo "Quoted mycommand" & cmd /v:on /c echo !TIME!.
Мартен Пеннингс

8
Simpler: echo %time% & *mycommand* & call echo %^time%. Смотрите также этот ответ .
Аасини

Если ваша команда выдает слишком много, может быть, проще просто сложить 2 раза:cmd /v:on /c "mycommand & echo begin=%time% endtime=!time!"
ZHANG Zikai

49

Если у вас открыто окно команд и вы вызываете команды вручную, вы можете отображать временную метку в каждом приглашении, например

prompt $d $t $_$P$G

Это дает вам что-то вроде:

23.03.2009 15:45:50,77

C:\>

Если у вас есть небольшой пакетный скрипт, который выполняет ваши команды, перед каждой командой должна быть пустая строка, например

(пустая строка)

myCommand.exe

(следующая пустая строка)

myCommand2.exe

Вы можете рассчитать время выполнения каждой команды по информации о времени в приглашении. Лучше всего было бы направить вывод в текстовый файл для дальнейшего анализа:

MyBatchFile.bat > output.txt

3
Подумал, что через пару лет за обсуждением хочу поблагодарить вас за то, что вы поделились с нами подсказкой. Я видел много трюков с CMD (больше от парня из bash), но этот избежал моего внимания.
Стив Ховард

Простой, элегантный, не требует установки и записи командных файлов для выполнения команды одним выстрелом и может рассчитывать каждый шаг в командном файле.
Мэтт

26

Так как другие рекомендуют устанавливать такие вещи, как бесплатные программы и PowerShell, вы также можете установить Cygwin , что даст вам доступ ко многим основным командам Unix, таким как time :

abe@abe-PC:~$ time sleep 5

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

Не уверен, сколько накладных расходов добавляет Cygwin.


41
Отвечая на вопросы Windows, Cygwin считается обманщиком :-)
mivk

14
Он указал, что пользователи ResourceKit, TimeMem, ptime.exe, PowerShell и другие утилиты начали обманывать первыми. Поэтому автор сделал ваш комментарий неуместным, прежде чем вы его написали.
Val

Я также проголосовал за это, поскольку нашел это самое простое решение, так как бесплатная программа Cmder включает bash! cmder.net Просто помните, что если вам нужно экранировать пробелы в bash, используйте черную черту \ непосредственно перед пробелом вместо «кавычек». например, cd / c / Program \ Files /
lukescammell

24

Не так элегантно, как некоторые функции Unix, но создайте cmd-файл, который выглядит следующим образом:

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

Это будет отображать время начала и окончания примерно так:

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
Предполагая, что вам не нужна переносимость между разными языками, вы также можете поместить findstr «current» или что-то в этом роде после «time <nul» (кстати, хорошее использование nul; я всегда использовал echo. | Time, но это не выглядит элегантно :)). И используйте «для», чтобы извлечь только время, а не текст.
Джои

2
Если включены расширения команд (то есть по умолчанию), в версии Win XP timeесть /tопция, которая просто отображает текущее системное время, без запроса ввода нового времени. Однако, когда вы делаете это, он отображает только часы и минуты, что может быть недостаточно для некоторых случаев. (См. Ответ Джона Сноу на этот вопрос.)
martineau

3
time /Tможно использовать, только если процесс выполняется в течение нескольких минут! time < nulуродливее, но точнее.
PhiLho

6
Вы также можете использовать тот, echo %time%который обеспечивает тот же формат и точность, что и time < nul, но вы избегаете Enter the new time:вывода ...
aschipfl

для не зависящих от локали и более точного использования времениwmic os get LocalDateTime
phuclv

19

Я использую бесплатное программное обеспечение под названием «GS Timer».

Просто создайте командный файл так:

timer
yourapp.exe
timer /s

Если вам нужно несколько раз, просто перенаправьте вывод timer / s в файл .txt.

Вы можете получить его здесь: Gammadyne's Free DOS Utilities


Разрешение составляет 0,1 секунды.


4
Я не думаю, что использование стороннего приложения можно было бы сделать «стандартными средствами».
Мартино

4
Спрашивающий имел в виду «без установки дополнительного программного обеспечения», но тогда для верного (принятого) ответа также требуется установить целый комплект ресурсов Windows 2003! Во всяком случае, timer.exe был идеальным для того, что я просто искал, спасибо!
Хьюго

1
Это засаженная ссылка. SoftPedia - это ферма кликов.
Том

@ Том, пожалуйста, объясни, что ты имеешь в виду под "установленной ссылкой"?
pepoluan

10
Вот прямая ссылка на собственную страницу разработчика: gammadyne.com/cmdline.htm#timer
Hugo

14

Я использую Windows XP и почему-то у меня не работает timeit.exe. Я нашел другую альтернативу - PTIME. Это работает очень хорошо.

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

Пример -

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

Хорошо работает и на Windows 8.1. Я переименовал мой в timer.exe, потому что я никогда не могу вспомнить имя ptime.
Брайан Бернс

11

Также есть TimeMem (март 2012):

Это утилита Windows, которая выполняет программу и отображает время ее выполнения, использование памяти и статистику ввода-вывода. По функциональности он похож на утилиту времени Unix.


10

Пока это не длится дольше, чем 24 часа ...

@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
Впечатляет, но я не думаю, что это работает, если в начале или конце есть 08 или 09, потому что они интерпретируются как восьмеричные. Мой ответ справляется с этим :)
Люк Сэмпсон

6

Вот

Постфиксная версия таймера:

Пример использования:

тайм-аут 1 | TimeIt.cmd

Execution took  ~969 milliseconds.

Скопируйте и вставьте это в какой-нибудь редактор, например Notepad ++, и сохраните его как 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

^ - По версии «Даниэль Спаркс»


5

Альтернативой измерению времени является просто «Get-Date». У вас нет проблем с пересылкой вывода и так далее.

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

Вывод:

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

Это было идеально для меня
Бретт

4

Это однострочник, который позволяет избежать отложенного расширения , что может нарушить определенные команды:

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

Вывод что-то вроде:

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

Для длительных испытаний заменить $Tна $D, $Tи %TIME%от %DATE%, %TIME%включать дату.

Чтобы использовать это внутри командного файла , замените %Zна %%Z.


Обновить

Вот улучшенный однострочный (без отложенного расширения тоже):

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

Вывод выглядит примерно так:

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

Этот подход не включает процесс создания нового cmdв результате, и при этом он не включает promptкоманду (ы).


4

В зависимости от версии Windows, которую вы используете, просто запуск bashпереведет вас в режим Bash. Это позволит вам использовать несколько команд, которые не доступны непосредственно в PowerShell (например, timeкоманда). Синхронизировать вашу команду теперь так же просто, как выполнить:

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

Примечание. Вы можете легко выйти из режима Bash и вернуться обратно в основную оболочку, запустившись exitв режиме Bash.

Это отлично сработало для меня (Windows 10) после опробования других методов (например Measure-Command), которые иногда приводят к нежелательной статистике. Надеюсь, это работает и для вас.


2
По состоянию на Windows 10 1607 лучший ответ.
CarpeDiemKopi

2

Если кто-то пришел сюда в поисках ответа на этот вопрос, есть функция Windows API GetProcessTimes(). Не так уж много работы, чтобы написать небольшую C-программу, которая запустит команду, сделает этот вызов и вернет время процесса.


3
Не так уж много работы, чтобы загрузить небольшую C-программу, которая запустит команду, сделает этот вызов (и намного больше предварительных измерений) и вернет время обработки.
Элазар Лейбович

@ElazarLeibovich powershell? Вы можете позвонить из C #.
KeyWeeUsr

@KeyWeeUsr вы можете использовать Windows API IIRC с сайта
Элазар Лейбович,

2

Это комментарий / правка Люка Сэмпсона, хороший timecmd.batи ответ на

По какой-то причине это дает мне вывод только в целых секундах ... что для меня бесполезно. Я имею в виду, что я запускаю timecmd pause, и это всегда приводит к 1,00 с, 2,00 с, 4,00 с ... даже к 0,00 с! Windows 7. - Камило Мартин 25 сентября '13 в 16:00 "

В некоторых конфигурациях разделители могут отличаться. Следующее изменение должно охватывать как минимум большинство западных стран.

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

В %time%миллисекундах работают в моей системе добавив , что «»

(* потому что сайт не позволяет оставлять комментарии и не отслеживает личность, хотя я всегда использую один и тот же гостевой адрес электронной почты, который в сочетании с ipv6 ip и отпечатком браузера браузера должен быть достаточным для однозначной идентификации без пароля)


Я прокомментировал это, прежде чем перейти к вашему ответу. Во всяком случае, автор сценария Люк мог нулевой колодки часы, минуты и секунды, а не только (оцифровки , которые сантисекундах , а не миллисекунды, BTW). Смотрите здесь: en.wiktionary.org/wiki/centisecond
Томаш Гандор

2

Вот мой метод, без преобразования и без мс. Полезно определить длительность кодирования (хотя и ограниченную 24 часами):

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

Не работает. Получение: Несбалансированная скобка. Несбалансированная скобка. Отсутствующий операнд.
Ричард Сандос

@RichardSandoz Работает нормально, несбалансированных скобок нет. Как ты это используешь?
MikeM

1

Следующий скрипт использует только «cmd.exe» и выводит количество миллисекунд с момента создания конвейера до момента завершения процесса, предшествующего скрипту. т.е. введите вашу команду и направьте ее к сценарию. Пример: «timeout 3 | runtime.cmd» должно дать что-то вроде «2990». Если вам нужны как выходные данные времени выполнения, так и выходные данные stdin, перенаправьте stdin перед конвейером - например: «dir / s 1> temp.txt | runtime.cmd» выведет вывод команды «dir» в «temp.txt» и напечатал бы среду выполнения к консоли.

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

Что ж, вместо рекурсивного вызова скрипта, подумайте о том, чтобы сделать это так call :calc. Я сделал это здесь. Код ссылки получить немного лучше. : D
Наду

Ошибка № 1 потерпит неудачу на 12-й час. Пример: « 0 : 23: 19,42» Ошибка № 2 Сбой, если десятичная точка не равна. тот же пример: "0:23:19 , 42" здесь десятичная точка, <__________> Хорошо попытался отредактировать, однако, что тупой **** в 'комиссии по утверждению редактирования' отклонил его - 3 из 5 проголосовали 'Это изменение также изменяется У многих авторов первоначальные намерения ». так что если вам захочется отредактировать удачу или просто сохранить ошибки - так «первоначальное намерение авторов остается неизменным». лицевая сторона
Наду

Невозможно вывести миллисекунды, если разрешение ваших часов едва достигает разрешения 1/100 секунды.
17

1

Ответ дриблио можно сделать немного короче (хотя и не очень читабельным)

@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

По замечанию Люка Сэмпсона, эта версия восьмерично безопасна, хотя задача должна быть выполнена за 24 часа.


Не работает. Отсутствует оператор, когда однозначный час.
Ричард Сандос

set _time=%time: =0%устраняет проблему с однозначным числом часов - замените в обоих местах.
Лаур

1
  1. В каталоге, где находится ваша программа, введите notepad mytimer.bat«Да», чтобы создать новый файл.

  2. Вставьте приведенный ниже код, заменив его YourApp.exeсвоей программой, затем сохраните.

    @echo off
    date /t
    time /t
    YourApp.exe
    date /t
    time /t
  3. Введите mytimer.batв командной строке и нажмите Enter.


7
время / т дает вам время только в формате ЧЧ: ММ. Чтобы рассчитать время выполнения исполняемого файла, вам обычно требуется больше точности ... Что-нибудь, что вы можете настроить, чтобы перейти к долям секунды? Я тестировал гуманного от JohnW (время <NUL), и что на самом деле дает время до 1 / 100s: HH: MM: SS.XX
благоговение

1

Мой код дает вам время выполнения в миллисекундах, до 24 часов, он не зависит от локали и учитывает отрицательные значения, если код выполняется до полуночи. он использует отложенное расширение и должен быть сохранен в файле cmd / bat.

перед вашим кодом:

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%

после вашего кода:

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

если вы хотите время выполнения в формате ЧЧ: мм: сс.000, добавьте:

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

переменная t2содержит ваше время выполнения, вы можете echo %t2%отобразить его.


1

После того, как Perl установит доступное решение по найму, запустите:

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

STDERR предшествует измеренным секундам

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

Использование подпрограммы для возврата времени в сотых долях секунды

::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» с региональным форматом, поддержкой 24 часа и смешанного ввода
Адаптация Aacini метода замены , без IF, только один FOR (мое региональное решение)

1: файл timer.bat находится где-то в% PATH% или текущем каталоге

@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

Использование:
таймер и эхо start_cmds & timeout / t 3 и эхо end_cmds и таймер
таймер и таймер "23: 23: 23,00"
таймер "23: 23: 23,00" и таймер
таймера "13.23.23,00" и таймер «03: 03: 03.00«
таймер и таймер »0: 00: 00.00« нет & cmd / v: вкл / с эхо до полуночи =! Timer_end!
Ввод теперь может быть смешанным, для тех маловероятных, но возможных изменений формата времени во время выполнения

2: Функция : таймер в комплекте с пакетным скриптом (пример использования ниже):

@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

:: чтобы проверить это, скопируйте и вставьте выше и ниже разделы кода

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 и CS, DS означают конец двоеточия, конец точки и набор двоеточий, набор точек - используется для поддержки смешанного формата


0

Следующий скрипт эмулирует время эпохи * nix, но он локальный и региональный. Он должен обрабатывать крайние случаи календаря, включая високосные годы. Если доступен Cygwin , значения эпох можно сравнить, указав параметр Cygwin .

Я нахожусь в EST, и сообщаемая разница составляет 4 часа, что является относительно правильным. Есть несколько интересных решений по удалению TZ и региональных зависимостей, но я не заметил ничего тривиального.

@ECHO off
SETLOCAL EnableDelayedExpansion

::
::  Emulates local epoch seconds
::

:: Call passing local date and time
CALL :SECONDS "%DATE%" "%TIME%"
IF !SECONDS! LEQ 0 GOTO END

:: Not testing - print and exit
IF NOT "%~1"=="cygwin" (
    ECHO !SECONDS!
    GOTO END
)

:: Call on Cygwin to get epoch time
FOR /F %%c IN ('C:\cygwin\bin\date +%%s') DO SET EPOCH=%%c

:: Show the results
ECHO Local Seconds: !SECONDS!
ECHO Epoch Seconds: !EPOCH!

:: Calculate difference between script and Cygwin
SET /A HOURS=(!EPOCH!-!SECONDS!)/3600
SET /A FRAC=(!EPOCH!-!SECONDS!)%%3600

:: Delta hours shown reflect TZ
ECHO Delta Hours: !HOURS! Remainder: !FRAC!

GOTO END

:SECONDS
SETLOCAL  EnableDelayedExpansion

    :: Expecting values from caller
    SET DATE=%~1
    SET TIME=%~2

    :: Emulate Unix epoch time without considering TZ
    SET "SINCE_YEAR=1970"

    :: Regional constraint! Expecting date and time in the following formats:
    ::   Sun 03/08/2015   Day MM/DD/YYYY
    ::   20:04:53.64         HH:MM:SS
    SET VALID_DATE=0
    ECHO !DATE! | FINDSTR /R /C:"^... [0-9 ][0-9]/[0-9 ][0-9]/[0-9][0-9][0-9][0-9]" > nul && SET VALID_DATE=1
    SET VALID_TIME=0
    ECHO !TIME! | FINDSTR /R /C:"^[0-9 ][0-9]:[0-9 ][0-9]:[0-9 ][0-9]" > nul && SET VALID_TIME=1
    IF NOT "!VALID_DATE!!VALID_TIME!"=="11" (
        IF !VALID_DATE! EQU 0  ECHO Unsupported Date value: !DATE! 1>&2
        IF !VALID_TIME! EQU 0  ECHO Unsupported Time value: !TIME! 1>&2
        SET SECONDS=0
        GOTO SECONDS_END
    )

    :: Parse values
    SET "YYYY=!DATE:~10,4!"
    SET "MM=!DATE:~4,2!"
    SET "DD=!DATE:~7,2!"
    SET "HH=!TIME:~0,2!"
    SET "NN=!TIME:~3,2!"
    SET "SS=!TIME:~6,2!"
    SET /A YEARS=!YYYY!-!SINCE_YEAR!
    SET /A DAYS=!YEARS!*365

    :: Bump year if after February  - want leading zeroes for this test
    IF "!MM!!DD!" GEQ "0301" SET /A YEARS+=1

    :: Remove leading zeros that can cause octet probs for SET /A
    FOR %%r IN (MM,DD,HH,NN,SS) DO (
        SET "v=%%r"
        SET "t=!%%r!"
        SET /A N=!t:~0,1!0
        IF 0 EQU !N! SET "!v!=!t:~1!"
    )

    :: Increase days according to number of leap years
    SET /A DAYS+=(!YEARS!+3)/4-(!SINCE_YEAR!%%4+3)/4

    :: Increase days by preceding months of current year
    FOR %%n IN (31:1,28:2,31:3,30:4,31:5,30:6,31:7,31:8,30:9,31:10,30:11) DO (
        SET "n=%%n"
        IF !MM! GTR !n:~3! SET /A DAYS+=!n:~0,2!
    )

    :: Multiply and add it all together
    SET /A SECONDS=(!DAYS!+!DD!-1)*86400+!HH!*3600+!NN!*60+!SS!

:SECONDS_END
ENDLOCAL & SET "SECONDS=%SECONDS%"
GOTO :EOF

:END
ENDLOCAL

Любопытно о понижении. Спасибо.
августа

0

Решение с использованием чистого PHP для cmd и одного env. переменная:

@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');"
  • нет необходимости в cygwin или ненадежных утилитах. Полезно, когда PHP доступен локально

  • Точность и формат вывода можно легко настроить

  • ту же идею можно перенести для PowerShell

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.