【问题标题】:How can I measure the time it takes for each iteration of a for loop?如何测量 for 循环的每次迭代所花费的时间?
【发布时间】:2015-02-15 02:19:19
【问题描述】:

如何使用这样的脚本来记录批处理脚本中 for 循环的每次迭代所花费的时间?我已经实现了这个来记录整个脚本的执行时间,但我想获取 for 循环的每次迭代的持续时间。

    @echo off

    rem ******************  MAIN CODE SECTION
    set STARTTIME=%TIME%

    rem Your code goes here (remove the ping line)
    ping -n 4 -w 1 127.0.0.1 >NUL

    set ENDTIME=%TIME%

    rem ******************  END MAIN CODE SECTION


    rem Change formatting for the start and end times
    for /F "tokens=1-4 delims=:.," %%a in ("%STARTTIME%") do (
       set /A "start=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100"
    )

    for /F "tokens=1-4 delims=:.," %%a in ("%ENDTIME%") do (
       set /A "end=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100"
    )

    rem Calculate the elapsed time by subtracting values
    set /A elapsed=end-start

    rem Format the results for output
    set /A hh=elapsed/(60*60*100), rest=elapsed%%(60*60*100), mm=rest/(60*100), rest%%=60*100, ss=rest/100, cc=rest%%100
    if %hh% lss 10 set hh=0%hh%
    if %mm% lss 10 set mm=0%mm%
    if %ss% lss 10 set ss=0%ss%
    if %cc% lss 10 set cc=0%cc%

    set DURATION=%hh%:%mm%:%ss%,%cc%

    echo Start    : %STARTTIME%
    echo Finish   : %ENDTIME%
    echo          ---------------
    echo Duration : %DURATION% 

输出:

    Start    : 11:02:45.92
    Finish   : 11:02:48.98
             ---------------
    Duration : 00:00:03,06

编辑:这就是我的实现的样子

@ECHO on
setlocal enabledelayedexpansion
cls

RMDIR c:\path1 /s /q
mkdir c:\path1
xcopy "\\path2\*" c:\path1 /s /i
cd c:\path3

for /f "tokens=*" %%a in ('dir /b /od') do set newest=%%a
cd c:\path1

sqlcmd -S server -i "\\path2\DropDatabases.sql"

for /D /r %%F IN ("*") DO ( 
    for %%G  IN ("%%F\*.extenstion1") DO xcopy "%%G" c:\path2\%newest% /y /i

    for /l %%A in (1,1,5) do (
        set STARTTIME=!TIME!

    for /f "delims=_" %%J IN ('forfiles /p "%%F" /m *.jmpt /c "cmd /c echo @path"')  DO start "program"  /D "c:\path3" /Wait program -r  %%J

    set ENDTIME=!TIME!
call :GetDuration !STARTTIME! !ENDTIME! 
    )
)

    exit /b
    :GetDuration
    set function_starttime=%1
    set function_endtime=%2

    rem Change formatting for the start and end times
    for /F "tokens=1-4 delims=:.," %%a in ("%function_starttime%") do (
        set /A "start=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100"
)

    for /F "tokens=1-4 delims=:.," %%a in ("%function_endtime%") do (
        set /A "end=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100"
)

    rem Calculate the elapsed time by subtracting values
    set /A elapsed=end-start

    rem Format the results for output
    set /A hh=elapsed/(60*60*100), rest=elapsed%%(60*60*100), mm=rest/(60*100), rest%%=60*100, ss=rest/100, cc=rest%%100
    if %hh% lss 10 set hh=0%hh%
    if %mm% lss 10 set mm=0%mm%
    if %ss% lss 10 set ss=0%ss%
    if %cc% lss 10 set cc=0%cc%

    set DURATION=%hh%:%mm%:%ss%.%cc%

    echo Start    : %function_starttime%
    echo Finish   : %function_endtime%
    echo          ---------------
    echo Duration : %DURATION%
    echo.

sqlcmd -S server -i "\\path2\query.sql"

pause

【问题讨论】:

    标签: windows batch-file for-loop time batch-processing


    【解决方案1】:

    有一个很好的包叫做“tictoc” 您只需将 tic(i) 放在循环的开头,将 toc() 放在循环的结尾。每次迭代后,您都会看到花费在它上面的确切时间(以秒为单位)。

    您可以在这里找到更多信息

    https://cran.rproject.org/web/packages/tictoc/tictoc.pdf

    【讨论】:

    • 链接中的错字。这是https://cran.r-project.org/web/packages/tictoc/tictoc.pdf。关于R(与batch-file无关)
    【解决方案2】:

    在 for 循环代码块内部的任一端设置 starttime 和 endtime 变量,并将所有转换和输出代码放入一个函数中。您还需要启用延迟扩展。

    @echo off
    setlocal enabledelayedexpansion
    cls
    
    rem ******************  MAIN CODE SECTION
    for /l %%A in (1,1,5) do (
        set STARTTIME=!TIME!
    
        rem Your code goes here (remove the ping line)
        ping -n 3 -w 1 127.0.0.1 >NUL
    
        set ENDTIME=!TIME!
        call :GetDuration !STARTTIME! !ENDTIME!
    )
    
    rem ******************  END MAIN CODE SECTION
    exit /b
    
    :GetDuration
    set function_starttime=%1
    set function_endtime=%2
    
    rem Change formatting for the start and end times
    for /F "tokens=1-4 delims=:.," %%a in ("%function_starttime%") do (
       set /A "start=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100"
    )
    
    for /F "tokens=1-4 delims=:.," %%a in ("%function_endtime%") do (
       set /A "end=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100"
    )
    
    rem Calculate the elapsed time by subtracting values
    set /A elapsed=end-start
    
    rem Format the results for output
    set /A hh=elapsed/(60*60*100), rest=elapsed%%(60*60*100), mm=rest/(60*100), rest%%=60*100, ss=rest/100, cc=rest%%100
    if %hh% lss 10 set hh=0%hh%
    if %mm% lss 10 set mm=0%mm%
    if %ss% lss 10 set ss=0%ss%
    if %cc% lss 10 set cc=0%cc%
    
    set DURATION=%hh%:%mm%:%ss%.%cc%
    
    echo Start    : %function_starttime%
    echo Finish   : %function_endtime%
    echo          ---------------
    echo Duration : %DURATION%
    echo.
    

    【讨论】:

    • 好吧,所以我有点困惑。我对批处理函数的经验几乎为零,您是在该代码中创建函数还是它们只是占位符?
    • :GetDuration 到脚本末尾的所有内容都是GetDuration 函数。你用call 调用它,就像它是它自己的脚本一样。参数的工作方式也相同。函数通常以命令goto :eof 结束,该命令位于文件的末尾,但由于在这种情况下它是脚本中的最后一件事,我可以不使用它。
    • 那么:GetDuration 应该跳出循环吗?
    • 是的!我提供的代码是一个功能齐全的示例。为了满足您的需求,您所要做的就是用您的代码替换 ping 命令(并更改循环类型)。
    • 好的小问题,如果我要测量的循环实际上在另一个 for 循环中呢?
    猜你喜欢
    • 2021-06-05
    • 1970-01-01
    • 2020-02-06
    • 1970-01-01
    • 2016-01-09
    • 2018-02-13
    • 1970-01-01
    • 2013-12-11
    • 2017-02-09
    相关资源
    最近更新 更多