Как долго выполняется пакетный файл для выполнения?

Как я могу написать script для вычисления времени, которое потребовалось для завершения script?

Я думал, что это будет так, но, очевидно, не..

@echo off
set starttime=%time%
set endtime=%time%

REM do stuff here

set /a runtime=%endtime%-%starttime%
echo Script took %runtime% to complete

Ответ 1

В исходном пакетном файле происходят две вещи. , но ни один из них не поможет в конечном итоге.

  • Независимо от вашего тестового метода, обязательно запишите время начала до операции и время окончания операции. Ваш образец этого не делает.

  • %time% оценивает что-то вроде "12: 34: 56.78", а команда SET /A не может вычитать их. Вам нужна команда, которая создает простую скалярную метку времени.

Я собирался сказать, что этого не может быть сделано, но пакетный язык намного эффективнее, чем ему дают кредит, так что вот простая реализация TIMER.BAT. Для записи, Pax избил меня до ответа, показывающего расщепление струны, пока я возился, и Йоханнес Рёссел предложил перевести арифметику за пределы измеряемой области:

@echo off
setlocal

rem Remeber start time. Note that we don't look at the date, so this
rem calculation won't work right if the program run spans local midnight.
set t0=%time: =0%

rem do something here.... but probably with more care about quoting.
rem specifically, odd things will happen if any arguments contain 
rem precent signs or carets and there may be no way to prevent it.
%*

rem Capture the end time before doing anything else
set t=%time: =0%

rem make t0 into a scaler in 100ths of a second, being careful not 
rem to let SET/A misinterpret 08 and 09 as octal
set /a h=1%t0:~0,2%-100
set /a m=1%t0:~3,2%-100
set /a s=1%t0:~6,2%-100
set /a c=1%t0:~9,2%-100
set /a starttime = %h% * 360000 + %m% * 6000 + 100 * %s% + %c%

rem make t into a scaler in 100ths of a second
set /a h=1%t:~0,2%-100
set /a m=1%t:~3,2%-100
set /a s=1%t:~6,2%-100
set /a c=1%t:~9,2%-100
set /a endtime = %h% * 360000 + %m% * 6000 + 100 * %s% + %c%

rem runtime in 100ths is now just end - start
set /a runtime = %endtime% - %starttime%
set runtime = %s%.%c%

echo Started at %t0%
echo Ran for %runtime%0 ms

Вы могли бы упростить арифметику и немного более честно относиться к общей точности этого, не беспокоясь о 100-й части второй части. Здесь он находится в действии, предполагая, что у вас есть команда сна или какое-то другое время:

C:> TIMER SLEEP 3
Script took 3000 ms to complete
C:> 

Изменить: Я пересмотрел код и его описание, как это предлагается в комментарии.

Я думаю, что, когда команда NT заменила COMMAND.COM на CMD.EXE, они думали, что они не уйдут, сделав ее совсем другой. Но на самом деле это почти совершенно новый язык. Многие из старых любимых команд имеют новые функции, если расширения включены.

Один из них - SETLOCAL, который мешает переменным изменять среду звонящего. Другой - SET /A, который дает вам замечательную сумму арифметики. Основной трюк, который я использовал здесь, - это новый синтаксис извлечения подстроки, где %t:~3,2% означает два символа, начинающихся со смещения 3 в значении переменной с именем t.

Для реального шокера взгляните на полное описание набора (попробуйте SET /? в подсказке), и если это вас не пугает, посмотрите FOR /? и обратите внимание, что он может анализировать текст из файлов...

Изменить 2: Исправлена ​​некорректная обработка полей времени, содержащих 08 или 09, сообщенных Frankie в комментариях. Изменил пару вещей и добавил несколько комментариев.

Обратите внимание, что здесь наблюдается явный надзор, который я, вероятно, не собираюсь исправлять. Он не будет работать, если команда запускается в другой день, чем заканчивается. То есть, он будет делать некоторую математику, связанную со временем дня, и сообщать о различии, но разница не будет означать много.

Исправить это, по крайней мере, предупредить об этом случае легко. Фиксировать его, чтобы делать правильные вещи, сложнее.

Изменить 3: Исправлена ​​ошибка, когда% h% не настроен должным образом на однократные часы. Это связано с тем, что% time% возвращает "9: 01: 23.45". Обратите внимание на пробел. Использование% time: = 0% заменяет пространство начальным нулем и% h% будет установлено правильно. Эта ошибка произошла только тогда, когда script пробежал от одной цифры до следующего.

Ответ 2

Это своего рода тангенциальный, но он может помочь вам.

У Microsoft есть программа timeit.exe, которая работает более или менее как расширенная версия команды unix 'time'. Он поставляется в ресурсе Windows Server 2003 Resource Kit, и он почти полностью заменил все время, когда я хотел сделать что-то вроде того, предлагая.

Возможно, стоит посмотреть.

Ответ 3

Отличная рутина. Однако, если расчет проходит через два дня, расчет неверен. Результат требует вычитания с 24 часов (8640000 сантиметров).

Также удалите одну из дубликатов команд "set" в соответствующей строке.

Обратите внимание, что региональные настройки влияют на формат функции TIME, а десятичное число - в Великобритании, а не в запятой.

Линии

rem, мы могли бы измерить время между днями

if %ENDTIME% LSS %STARTTIME% set set /A DURATION=%STARTTIME%-%ENDTIME%

нужно изменить на

rem, мы могли бы измерить время в течение дней

if %ENDTIME% LSS %STARTTIME% set /A DURATION=8640000 - (%STARTTIME% - %ENDTIME%)

Ответ 4

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

Следующий script будет задерживать 10-секундную команду ping с возможностью пересечения границы одного дня без привязки к отрицательным числам. Небольшое улучшение позволило бы ему пересечь многие дневные границы.

@echo off
setlocal enableextensions enabledelayedexpansion
set starttime=%time%
ping -n 11 127.0.0.1 >nul: 2>nul:
set endtime=%time%

set /a hrs=%endtime:~0,2%
set /a hrs=%hrs%-%starttime:~0,2%

set /a mins=%endtime:~3,2%
set /a mins=%mins%-%starttime:~3,2%

set /a secs=%endtime:~6,2%
set /a secs=%secs%-%starttime:~6,2%

if %secs% lss 0 (
    set /a secs=!secs!+60
    set /a mins=!mins!-1
)
if %mins% lss 0 (
    set /a mins=!mins!+60
    set /a hrs=!hrs!-1
)
if %hrs% lss 0 (
    set /a hrs=!hrs!+24
)
set /a tot=%secs%+%mins%*60+%hrs%*3600

echo End     = %endtime%
echo Start   = %starttime%
echo Hours   = %hrs%
echo Minutes = %mins%
echo Seconds = %secs%
echo Total   = %tot%

endlocal

Ответ 5

Проверьте этот script, который будет извлекать время через WMI, чтобы он был независимым от региона.

@echo off
::::::::::::::::::::::::::::::::::::::::::
::  TimeDiff v1.00 by LEVENTE ROG       ::
::       www.thesysadminhimself.com     ::
::::::::::::::::::::::::::::::::::::::::::
 
::[ EULA ]:::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::  Feel free to use this script. The code can be redistributed  ::
::  and edited, but please keep the credits.                     ::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
::[ CHANGELOG ]::::::::::::::
::  v1.00 - First Version  ::
:::::::::::::::::::::::::::::
 
 
FOR /F "skip=1 tokens=1-6" %%A IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Second /Format:table ^| findstr /r "."') DO (
 set Milisecond=%time:~9,2% 
 set Day=%%A
 set Hour=%%B
 set Minute=%%C
 set Second=%%D
)
set /a Start=%Day%*8640000+%Hour%*360000+%Minute%*6000+%Second%*100+%Milisecond%
 
::
::
:: PUT COMMANDS HERE
ping www.thesysadminhimself.com
::
::
 
FOR /F "skip=1 tokens=1-6" %%A IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Second /Format:table ^| findstr /r "."') DO (
 set Day=%%A
 set Hour=%%B
 set Minute=%%C
 set Second=%%D
)
set Milisecond=%time:~9,2% 
set /a End=%Day%*8640000+%Hour%*360000+%Minute%*6000+%Second%*100+%Milisecond%
set /a Diff=%End%-%Start%
set /a DiffMS=%Diff%%%100
set /a Diff=(%Diff%-%DiffMS%)/100
set /a DiffSec=%Diff%%%60
set /a Diff=(%Diff%-%Diff%%%60)/60
set /a DiffMin=%Diff%%%60
set /a Diff=(%Diff%-%Diff%%%60)/60
set /a DiffHrs=%Diff%
 
:: format with leading zeroes
if %DiffMS% LSS 10 set DiffMS=0%DiffMS!%
if %DiffSec% LSS 10 set DiffMS=0%DiffSec%
if %DiffMin% LSS 10 set DiffMS=0%DiffMin%
if %DiffHrs% LSS 10 set DiffMS=0%DiffHrs%
 
echo %DiffHrs%:%DiffMin%:%DiffSec%.%DiffMS%

Ответ 6

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

Взгляните на нижнюю часть эту тему форума для примера того, как сделать последнее.

Я также предполагаю, что это опечатка, но вы действительно хотите установить endtime после обработки.