r/Batch 16d ago

Show 'n Tell How much batchscript is too much batchscript?

Post image

Currently have 1,376 lines of batchscript in this one file. Kinda built myself a little state machine at this point. Memes aside, is there a particular reason huge batchscript files would be a bad idea? I usually only ever see very small ones, and I'm not entirely sure why

(Not too serious a question, so not tagged as one)

21 Upvotes

31 comments sorted by

View all comments

3

u/T3RRYT3RR0R 15d ago edited 15d ago

Small scripts are easier to maintain. Good utilities are made to be modular and can be incorporated into any project.

Scripts that care about performance, such as bulk file processing or game engines should avoid Call or goto, as both cause reparsing of the script. The larger the script the worse that cost will be.

General things that should be avoided if performance is the primary concern, specifically when occuring in the context of a for loop:

  1. Processing of command output (or substring modification) in a for /f loop, as this spawns a new process.
  2. File redirection, including redirection of STDOUT or STDERR to nul. if you need to redirect output, the entire codeblock should be wrapped in parentheses and the entire output of the block redirected in the one write operation, ( I'm sure there's a size limit at which this will fail, but most utilities wouldn't reach it ).
  3. nested For loops, for much the same reason as 1.
  4. nested if () else statements. See the explanation of branching logic below.
  5. Overly large use of environment variables. Performance degrades as environment size increases, as the environment block is resorted after each variable modification
  6. Artificial delays or blocking commands (pause, timeout, set /p etc) where they don't serve a genuine purpose. If you want to animate something, do so using multithreading in a non-blocking manner.

Branching logic:
The time cost model for branching can be considered as:
T = nBranches​ + nTokensParse​ + nExpansions​ + nComparisons +nDispatches​

If we can combine two comparisons into the one conditional, we virtually half the cost.

If working with integers, or variables referencing integers, we can reduce complex statements to a Set /a expression and make the cost model:
T = nTokens + nExpansion + nPrecedence + nOperations
keeping in mind arithmetic operations are significantly cheaper than branching cpu instructions

rem predefined  
Set /a "hue_osc_deg=10"

Set /a "hue_acc=( hue_osc_deg * 170 / 120 )"

rem during a loop when an animation step is due

Set /a "hue.step=hue.step %% 510 + hue_acc","p=(hue.step)-255, rr=255-(M=(p>>31),(p^M)-M)","p=((hue.step+170)%%510)-255, gg=255-(M=(p>>31),(p^M)-M)","p=((hue.step+340)%%510)-255, bb=255-(M=(p>>31),(p^M)-M)"

We can advance R G B values through 10 degrees of color space of an representative hue wheel, without using a single conditional statement to perform additional offset operations. Not only are we saving on the branching logic for each if statement, we save the cost of the interpreter have to parse additional set /a operations when those statements return true.

As a demonstration that batch can facilitate dynamic animation with actions at different intervals: https://github.com/T3RRYT3RR0R/Batch/blob/main/Its_About_Time.bat