2009-04-11 44 views
17

¿Cómo puedo escribir una secuencia de comandos para calcular el tiempo que tardó en completar la secuencia de comandos?¿Cuánto demora ejecutar un archivo por lotes?

pensé que este sería el caso, pero, obviamente, no ..

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

REM do stuff here 

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

shouldn' ¿Estableces el tiempo de finalización después de hacer algunas cosas? ¿es un error tipográfico? –

+0

bueno, podría simplemente hacer "time ./myscript" – mpen

+0

@mark, en una instalación estándar de Windows, el tiempo es un comando integrado en CMD.EXE que establece o muestra la hora actual del día. – RBerteig

Respuesta

1

No se puede hacer aritmética vez directamente en el procesamiento por lotes, por lo que se tendrá un programa externo para calcular la diferencia horaria , o extraer cada parte del tiempo y hacer aritmética de esa manera.

Eche un vistazo a la parte inferior de this forum thread para ver un ejemplo de cómo hacer esto último.

También asumo que es un error tipográfico, pero desea asegurarse de configurar endtimedespués del procesamiento.

2

Mi preferencia personal es la instalación de Cygwin y utilizar el comando time pero, si realmente tiene hacerlo como un archivo por lotes, que no sólo puede restar las cuerdas, hay que tratarlos como partes.

La siguiente secuencia de comandos cronometrará un comando de ping de 10 segundos con la capacidad de cruzar un límite de un solo día sin atarse en números negativos. Una ligera mejora le permitiría cruzar muchos límites de un día.

@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

Esto es algo tangencial, pero puede serle útil.

Microsoft tiene un programa timeit.exe que funciona más o menos como una versión mejorada del comando 'time' de unix. Viene en el Windows Server 2003 Resource Kit, y ha reemplazado casi todas las veces que he querido hacer algo como lo que estás sugiriendo.

Puede valer la pena mirar.

35

Dos cosas saltan sobre el archivo de proceso original. pero ninguno de los dos ayudará en el largo plazo.

  1. Sea cual sea su método de referencia, asegúrese de capturar la hora de inicio antes de la operación, y la hora de finalización después de la operación. Tu muestra no hace eso.

  2. %time% evalúa algo así como "12: 34: 56.78", y el comando SET /A no puede restar esos. Necesita un comando que produzca una marca de tiempo escalar simple.

que iba a decir que no se puede hacer, pero el lenguaje por lotes es mucho más poderoso de lo que se da el crédito para, asi que aquí hay una implementación sencilla de TIMER.BAT. Para el registro, Pax me adelantó una respuesta que muestra la división de la cadena mientras estaba jugueteando, y Johannes Rössel sugirió trasladar la aritmética fuera de la región medido:

@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 

Se podría simplificar la aritmética y ser un poco más Honesto sobre la precisión general de esto al no molestarse con las centésimas de una segunda parte.Aquí está en acción, suponiendo que tiene una orden de suspensión o alguna otra pérdida de tiempo:

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

Editar: revisé el código y su descripción como se sugiere en un comentario.

Creo que cuando el equipo de NT reemplazó COMMAND.COM con CMD.EXE, pensaron que no se saldría con la tarea de hacerlo muy diferente. Pero, en efecto, es casi un lenguaje completamente nuevo. Muchos de los viejos comandos favoritos tienen nuevas características si las extensiones están habilitadas.

Uno de ellos es SETLOCAL que impide que las variables modifiquen el entorno de la persona que llama. Otro es SET /A que le da una cantidad notable de aritmética. El truco principal que he usado aquí es la nueva sintaxis de extracción de subcadena donde %t:~3,2% significa los dos caracteres que comienzan en el desplazamiento 3 en el valor de la variable llamada t.

Para una sorpresa real, eche un vistazo a la descripción completa del conjunto (intente SET /? en un aviso) y si eso no lo asusta, mire FOR /? y observe que puede analizar texto de archivos ...

Edición 2: fijos mal manejo de los campos de tiempo que contienen 08 o 09 reportado por Frankie en los comentarios. Pellizcó un par de cosas y agregó algunos comentarios.

Tenga en cuenta que hay un deslumbramiento evidente que probablemente no voy a solucionar. No funcionará si el comando comienza en un día diferente de lo que termina. Es decir, hará algunas matemáticas relacionadas con la hora del día e informará una diferencia, pero la diferencia no significará mucho.

Arreglarlo para al menos advertir sobre este caso es fácil. Repararlo para hacer lo correcto es más difícil.

Editar 3: Error reparado donde el% h% no está configurado correctamente para horas de un solo dígito. Esto se debe a%% return% "9: 01: 23.45". Observe el espacio. Usar% time: = 0% reemplaza el espacio con un cero inicial y% h% se establecerá correctamente. Este error solo ocurrió cuando un script se ejecutó de una hora a la siguiente.

+0

+1 para hacer un esfuerzo adicional ... puede explicar el negocio set/a (iniciado en Linux actualmente) – ojblass

+0

set/a hace aritmética en Batch. Lo que hace aquí es reducir todo a 1/100 de segundo. Luego puedes simplemente restarlos ya que ambos son solo números. – Joey

+0

Es posible que desee hacer todos los cálculos después de que se ejecute el comando, aunque ... las matemáticas en cmd no son exactamente rápidas, así que simplemente guarde la hora de inicio y revísela después de que su comando haya terminado para que no cuente. el momento del comando. No sé si hace una diferencia, al parecer no – Joey

2

Echa un vistazo a esta secuencia de comandos que recuperará el tiempo a través de WMI por lo que es independiente de configuración regional.

@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 buena solución, pero es lenta, cada marca de tiempo necesita ~ 100ms-200ms (en mi pc Core2 Duo de 2.4GHz) – jeb

3

Excelente pequeña rutina. Sin embargo, si el cálculo abarca dos días, el cálculo es incorrecto. El resultado debe restar de 24 horas (8640000 centiseconds).

Elimine también uno de los comandos 'set' duplicados en la línea correspondiente.

Tenga en cuenta que las configuraciones regionales afectan el formato de la función TIME, siendo el decimal una tapa en el Reino Unido en lugar de una coma.

Las líneas

reales que podrían haber medido el tiempo de días entre medio

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

necesidad de cambiar a

rem podríamos haber medido el tiempo a través de días

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