web-dev-qa-db-ja.com

バッチファイルの実行にはどのくらい時間がかかりますか?

スクリプトが完了するまでにかかった時間を計算するスクリプトを作成するにはどうすればよいですか?

私はこれが当てはまると思いましたが、明らかにそうではありません。

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

REM do stuff here

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

元のバッチファイルについては、2つのことが飛び出します。 しかし、どちらも長期的には役に立ちません。

  1. ベンチマーク方法が何であれ、操作の開始時間と終了時間を必ずキャプチャしてください。あなたのサンプルはそれをしません。

  2. %time%は「12:34:56.78」のように評価され、SET /Aコマンドはそれらを減算できません。単純なスカラータイムスタンプを生成するコマンドが必要です。

私はそれができないと言うつもりでしたが、バッチ言語はそれが信用されているよりもはるかに強力なので、ここにTIMER.BATの簡単な実装があります。記録のために、Paxは私がいじり回っている間に文字列が分割されることを示す答えに私を打ち負かし、JohannesRö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分の1秒の部分を気にしないことで、算術を単純化し、これの全体的な精度についてもう少し正直にすることができます。スリープコマンドまたはその他の時間の浪費があると仮定して、ここで動作しています。

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

編集:コメントで提案されているように、コードとその説明を修正しました。

NTチームがCOMMAND.COMをCMD.EXEに置き換えたとき、彼らはそれを大きく変えることで逃げられないと思ったと思います。しかし実際には、それはほとんど完全に新しい言語です。拡張機能が有効になっている場合、古いお気に入りのコマンドの多くに新しい機能があります。

それらの1つはSETLOCALであり、変数が呼び出し元の環境を変更するのを防ぎます。もう1つはSET /Aで、これは驚くべき量の算術演算を提供します。ここで使用した主なトリックは、新しい部分文字列抽出構文です。ここで、%t:~3,2%は、tという名前の変数の値のオフセット3から始まる2文字を意味します。

本当のショッカーについては、セットの完全な説明を見て(プロンプトでSET /?を試してください)、それでも怖くない場合は、FOR /?を見て、テキストを解析できることに注意してください。ファイル.。

編集2:コメントでFrankieによって報告された08または09を含む時間フィールドの誤った処理を修正しました。いくつかの調整を行い、いくつかのコメントを追加しました。

ここには明白な見落としがあり、おそらく修正するつもりはないことに注意してください。コマンドが終了日とは別の日に開始された場合は機能しません。つまり、時刻に関連する計算を行い、違いを報告しますが、違いはあまり意味がありません。

少なくともこのケースについて警告するように修正するのは簡単です。正しいことをするためにそれを修正することはより困難です。

編集3:%h%が1桁の時間に正しく設定されないエラーを修正しました。これは、%time%が「9:01:23.45」を返すためです。スペースに注意してください。 %timeの使用:= 0%はスペースを先行ゼロに置き換え、%h%が正しく設定されます。このエラーは、スクリプトが1桁の時間から次の時間に実行された場合にのみ発生しました。

38
RBerteig

これは一種の接線ですが、役立つ場合があります。

Microsoftには、unixの「time」コマンドの拡張バージョンのように機能するtimeit.exeプログラムがあります。これは Windows Server 2003 Resource Kit に含まれており、あなたが提案しているようなことをしたいと思っていたときは、ほとんど置き換えられています。

一見の価値があるかもしれません。

4
Dan Olson

優れた小さなルーチン。ただし、計算が2日間にわたる場合、計算は正しくありません。結果は24時間(8640000センチ秒)から引く必要があります。

また、関連する行の重複する「set」コマンドの1つを削除します。

地域の設定はTIME関数の形式に影響することに注意してください。英国では、小数はコンマではなくピリオドです。

台詞

rem私たちは日の間の時間を測定したかもしれません

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

に変更する必要があります

何日にもわたって時間を測定したかもしれないレム

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

私の個人的な好みは、Cygwinをインストールしてtimeコマンドを使用することですが、実際にhaveをバッチファイルとして実行する場合は、文字列を減算するだけでは不十分です。それらを部品として扱うために。

次のスクリプトは、負の数に縛られることなく1日の境界を越える機能を備えた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
2
paxdiablo

地域の設定に依存しないように、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%
2
Water Cooler

バッチスクリプトで直接時間演算を実行することはできないため、時間差を計算するための外部プログラムが必要になるか、時間の各部分を抽出してその方法で演算を実行する必要があります。

後者の方法の例については、 このフォーラムスレッド の下部をご覧ください。ここから抜粋:

 @ echo off 
 cls 
 REM ============================== ==================== ====== 
 REM =設定日時形式= 
 REM ====== ================================================== 
 set DT =%DATE %% TIME%
 set year =%DT:〜10,4%
 set mth =%DT:〜4,2%
 set date =%DT:〜7,2%
 set hour =%DT:〜15,2%
 set min =%DT:〜18,2%
 set sec =%DT:〜21,2%
 set newDT =%year%_%mth%_%date %% hour %% min %% sec%
 
 set hour = 14 
 set min = 10 
 
 REM ============================ === 
 REM =終了時刻の取得= 
 REM ============================== = 
 set EndTime =%TIME%
 set EndHour =%EndTime:〜0,2%
 set EndMin =%EndTime:〜3,2%
 
 
 REM =============================== 
 REM =違いを見つける= 
 REM =============================== 
 set/a Hour_Diff = EndHour-時間> nul 
 set/a Min_Diff = EndMin-min> nul 
 
 
 REM ================ =============== 
 REM =アワーハンドチェンジ? = 
 REM =============================== 
 IF [%Hour_Diff] == [0](
 
 Set Duration =%Min_Diff%
)ELSE(
 
 Set/a Duration = 60-%Min_Diff%> nul 
)
 
 
 echo開始時間=%hour%:%min%
 echo終了時間=%EndHour%:%EndMin%
 echo。
 echo Min Diff =%Min_Diff%
 echo。
 echo time Difference(mins)=%Duration%

また、タイプミスだと思いますが、必ずendtimeafter処理を設定する必要があります。

1
lc.