2009-04-11 4 views
17

Как написать скрипт, чтобы вычислить время выполнения сценария?Как долго выполняется пакетный файл для выполнения?

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

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

REM do stuff here 

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

не должны» t вы устанавливаете время окончания после того, как делаете что-то? это опечатка? –

+0

ну, вы могли бы просто сделать «время ./myscript» – mpen

+0

@mark, на складе Установка Windows, время - это команда, встроенная в CMD.EXE, которая устанавливает или отображает текущее время суток. – RBerteig

ответ

1

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

Посмотрите на нижнюю часть this forum thread на примере того, как это сделать.

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

2

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

В следующем скрипте будет выполняться 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 
4

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

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

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

35

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

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

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

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

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

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

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

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

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

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

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

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

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

+0

+1 за то, что вы несете лишнюю милю ... можете ли вы объяснить set/a business (загружается в Linux в настоящее время) – ojblass

+0

set/a выполняет арифметику в пакете. То, что он здесь делает, сокращает все до 1/100 секунды. Впоследствии вы можете просто вычесть их, так как они оба являются просто цифрами. – Joey

+0

Возможно, вы захотите выполнить всю математику после выполнения вашей команды, хотя ... математика в cmd не совсем быстра, поэтому просто сохраняйте время начала и играйте с ней после завершения вашей команды, чтобы она не подсчитывалась время команды. Не знаю, имеет ли это значение, по-видимому, не – Joey

2

Проверьте этот скрипт, который будет извлекать время через 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% 
+0

+1 приятное решение, но оно медленное, каждая временная метка требует ~ 100 мс-200 мс (на моем процессоре Core 2 Duo 2,4 ГГц) – jeb

3

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

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

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

Линия

бэр мы могли бы измерили время Inbetween дней

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

необходимости изменения в

бэр мы могли бы измерили время через дни

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

 Смежные вопросы

  • Нет связанных вопросов^_^