2

Suppose I have a batch file.

This batch file has a 'subroutine' labeled :AppndLog and it's purpose is to append a log file.

This routine starts at line - let's say 540. Now - other 'subroutines' thereafter may call this same Label but ALL of these routines are AFTER the :AppndLog label. . . .

So the question goes - is it more efficient to place this :AppndLog (and any other widely accessed 'routines') at the END of the file instead of at the beginning? Suppose this batch file has 7k lines of actions. . .

Does CMD.Exe interpret this and start the search for the label at the line it is first called, going to the end of the file and looping around, or does it go to the beginning of the file first?

Bonus points - does the Goto :EOF command trudge through the lines in between an end of subroutine to the end of the file?

It is much faster for me to simply echo the data to log using >>%log% at the point where I Call this routine but I lose the ability to output the date on each line without making yet another call somewhere else. . . (A real "FUN" delay was making the :AppndLog routine call a :GetDate routine where the date info at the beginning was produced. . . .

REM ╔══════════════════════════════════════════════════════╗
REM ║  -AppndLog-                                          ║
REM ║Appends log file with provided data if Logging GEQ #  ║
REM ╚══════════════════════════════════════════════════════╝

REM <<<-_-_-_-_-_BEGIN :AppndLog_-_-_-_-_->>>
 
 :AppndLog [Logging Level Check] [Data to Append]
 REM If "!Logging!" GEQ "2" Echo Append Data to Log. >>%log%
 REM for /f "Tokens=1,2 Delims=." %%a in ('wmic os get localdatetime ^|Findstr /R ^^[0-9]') do (set UTCDate=%%a & set curMS=%%b)
 REM Call :GetDate
 set myDate=!date:/=!
 set myTime=!time::=!
 set myTime=!myTime:.=!
 set "fullDate=!myDate!!myTime!"

 If not "%~1"=="" (
   Echo !fullDate! :: %~1 >>%log%
   If "!Verbose!" GEQ "3" Echo %~2
 ) Else (
   Echo !fullDate! >>%log%
   If "!Verbose!" GEQ "3" Echo.
 )
 
 Goto :EOF
REM <<<-_-_-_-_-_END :AppndLog_-_-_-_-_->>>
k1dfr0std
  • 379
  • 1
  • 15
  • 2
    Both `goto label` and `call :label` search the label from the line after the goto/call onwards. If not found, continue the search from the beginning of the file. This means that is more efficient to place the target labels and subroutines _below_ the calling line (at the end of the file). The `goto :EOF` form does _not_ search; it terminate the subroutine/file immediately – Aacini Feb 23 '23 at 04:28
  • OK - this is what I feared! I'll try repositioning the called routine at the bottom of the file - save it at least a few hundred lines to search through . . . . – k1dfr0std Feb 23 '23 at 06:37
  • That made considerable difference in performance. Neat! Mind putting in an answer so I can mark it for ya? – k1dfr0std Feb 23 '23 at 09:08
  • 1
    For such a large batch file it would be much more efficient if the batch file creates first `"%TEMP%\%~n0_AppendLog.cmd"` with the command lines to execute, then always calls `"%TEMP%\%~n0_AppendLog.cmd"` and finally deletes `"%TEMP%\%~n0_AppendLog.cmd"`. – Mofi Feb 23 '23 at 11:14
  • @Mofi - that's a wonderful idea - I will look into that - not too many lines/modifications to create the "module" this way, then assign it a variable - so my calls would go from `Call :AppndLog "#" "Text To Append"` to `Call !AppndLog! "#" "Text To Append"` where I establish this with `set AppndLog="%TEMP%\%~n0_AppndLog.cmd"` and utilize as such. – k1dfr0std Feb 24 '23 at 00:11

1 Answers1

2

Both goto label and call :label search the label from the line after the goto/call onwards. If not found, continue the search from the beginning of the file. This means that is more efficient to place the target labels and subroutines below the calling line (at the end of the file).

The goto :EOF form does not search; it terminates the subroutine/file immediately. The exit /B command is equivalent to goto :EOF I used to use exit /B to end subroutines, and goto :EOF to end the main Batch file.

Bonus information

This behavior allows to repeat the same label so a goto repeatedLabel will always go to the next label placed after the goto. This is useful when there are multiple goto's to near forward labels. In order to make clear this purpose and not be confused with an error, you can use the same method that MASM32 use for the same purpose: call @F the repeated label:

echo First goto near forward label
goto @F

echo This don't appears

:@F
echo Second goto near forward label
goto @F

echo Neither this appears...

:@F
echo OK
Aacini
  • 65,180
  • 12
  • 72
  • 108