How to speed up a batch script

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
Sounak@9434
Posts: 100
Joined: 16 Dec 2016 22:31

How to speed up a batch script

#1 Post by Sounak@9434 » 22 Dec 2016 09:22

Okay, keeping small thing small,
the title says it all (hey that rhymes :D)
Anyway, I want to know how to speed up any batch file.
I know that the way of approaching the final motive matters a lot and each batch file is different(blah blah blah).
For my problem at first I searched in the internet and found some webpages but mostly they are telling about a specific script so I thought about asking here.
I want to know how to speed up any individual batch files. Like using this command instead of that. Or using this command in this way instead of that. Or using this tool instead of that etc.

Thanks in advance.
Last edited by Sounak@9434 on 26 Dec 2016 05:52, edited 1 time in total.

TSnake41
Posts: 12
Joined: 17 Dec 2016 12:49

Re: How to speed up a batch script

#2 Post by TSnake41 » 22 Dec 2016 10:51

The speed of a batch script mostly depend of cmd.exe/csrss.exe, and a little of the batch script itself.

So, alternatives cmd.exe are very rare and rarely used but you can give a try to Dos9 : viewtopic.php?f=3&t=5538 (if you can, build from source to get new features and fixes like pushd/popd)

aGerman
Expert
Posts: 4654
Joined: 22 Jan 2010 18:01
Location: Germany

Re: How to speed up a batch script

#3 Post by aGerman » 22 Dec 2016 11:17

Batch is slow by design. The main reason is that half of the commands are external utilities. That means as soon as you call such a tool a new process has to be scheduled by the operating system. That takes a lot of time, especially if you call it umpteen times from within a loop. Whenever you have the choice use an internal command rather than an external. I wrote a little batch code that computes the commands outputted by the HELP command and displays whether they are internal functions of cmd.exe or external utilities.

Code: Select all

@echo off &setlocal EnableDelayedExpansion
set /a int=0, ext=0
for /f %%i in ('help^|findstr /rbc:"[A-Z][ABCDEFGHIJKLMNOPQRSTUVWXYZ]"') do (
  for /f "tokens=1,2 delims=?" %%j in ("%%i.exe?%%i.com") do (
    if "%%~$PATH:j%%~$PATH:k"=="" (
      set /a int+=1
      set "line=%%i                                                  "
      echo !line:~,50! - internal
    ) else (
      set /a ext+=1
      echo %%i "%%~$PATH:j%%~$PATH:k"
    )
  )
)

echo(
echo internal %int%
echo external %ext%
pause>nul



We had some discussions in the past how to speed up the start of external tools. E.g. normally you would simply write FINDSTR to call C:\Windows\System32\findstr.exe. That means the process has to search the tool using two variables. 1) the directories saved in %PATH% and 2) the file extension saved in %PATHEXT%. That takes time. Instead you could empty these variables and call the tools by their full name.


Avoid using GOTO LABEL or CALL :LABEL if you can use a FOR (/L) loop instead. Labels have to be searched in the batch file. The order is top to down. It resumes searching at the top of the file if the end was reached without finding it. The longer the file the more time it takes.


But generally spoken: If you have a performance-critical task then don't use batch and prefer compiled languages over interpreted languages.


Steffen

ShadowThief
Expert
Posts: 1160
Joined: 06 Sep 2013 21:28
Location: Virginia, United States

Re: How to speed up a batch script

#4 Post by ShadowThief » 22 Dec 2016 11:40

It really depends on your existing code; it's not like in VBA where you can say Application.ScreenUpdating=False and the whole thing speeds up by 90%.

Sounak@9434
Posts: 100
Joined: 16 Dec 2016 22:31

Re: How to speed up a batch script

#5 Post by Sounak@9434 » 26 Dec 2016 06:06

I have used for (/l) in batch scripts to trigger loops and also somehow found a way to trigger endless loop.

Code: Select all

for /l %%a in (1,0,2) do (%command%)

but I was unable to break out of a for loop. Seems like goto label or exit /b does not works inside a for loop.
Any ideas anyone?

aGerman
Expert
Posts: 4654
Joined: 22 Jan 2010 18:01
Location: Germany

Re: How to speed up a batch script

#6 Post by aGerman » 26 Dec 2016 06:50

You can simplify the infinite loop using an empty pair of parentheses.

Code: Select all

for /l %%i in () do ...

However you still can't break the FOR /L loop. The only way is using EXIT which will quit the batch execution. You could run another process if you want to use this method (takes time to load the process etc...) or you have to use GOTO to perform the loop.
See this discussion:
viewtopic.php?t=2707

Steffen

Sounak@9434
Posts: 100
Joined: 16 Dec 2016 22:31

Re: How to speed up a batch script

#7 Post by Sounak@9434 » 26 Dec 2016 07:11

aGerman wrote:You can simplify the infinite loop using an empty pair of parentheses.

Code: Select all

for /l %%i in () do ...

However you still can't break the FOR /L loop. The only way is using EXIT which will quit the batch execution. You could run another process if you want to use this method (takes time to load the process etc...) or you have to use GOTO to perform the loop.
See this discussion:
viewtopic.php?t=2707

Steffen

Thanks Steffen but it does not actually solves my problem. I wanted a for loop because it's faster than goto but if it needs creating a seperate process it's definitely gonna be slower. Gotta find another way to achive this.

aGerman
Expert
Posts: 4654
Joined: 22 Jan 2010 18:01
Location: Germany

Re: How to speed up a batch script

#8 Post by aGerman » 26 Dec 2016 07:21

Sounak@9434 wrote:Gotta find another way to achive this.

Good luck.

Sounak@9434
Posts: 100
Joined: 16 Dec 2016 22:31

Re: How to speed up a batch script

#9 Post by Sounak@9434 » 27 Dec 2016 09:41

O.k. So after googling for hours I found that that there is no way to break an infinite for loop. Indirectly we can use a while macro.
But theoritically speaking which one should be faster on avarage Aacini's while macro or a goto :label loop?

aGerman
Expert
Posts: 4654
Joined: 22 Jan 2010 18:01
Location: Germany

Re: How to speed up a batch script

#10 Post by aGerman » 27 Dec 2016 16:37

As I said, the larger the script the longer does it take to find the label. Just do some tests to figure out which is faster in your case.

Steffen

misol101
Posts: 475
Joined: 02 May 2016 18:20

Re: How to speed up a batch script

#11 Post by misol101 » 28 Dec 2016 05:29

Sounak: Did you try the variant I used in some of the scripts I posted recently? The structure is:

Code: Select all

(set STOP=)
:LOOP
for /L %%1 in (1,1,300) do if not defined STOP (
...
(IF stopcondition set STOP=1)
)
IF not defined STOP goto LOOP


So as you can see the for loop itself is not infinite, But there is only one goto per 300 loops (or as many as you choose).

I think einstein1969 posted this first.

Sounak@9434
Posts: 100
Joined: 16 Dec 2016 22:31

Re: How to speed up a batch script

#12 Post by Sounak@9434 » 28 Dec 2016 06:02

misol101 wrote:Sounak: Did you try the variant I used in some of the scripts I posted recently? The structure is:

Code: Select all

(set STOP=)
:LOOP
for /L %%1 in (1,1,300) do if not defined STOP (
...
(IF stopcondition set STOP=1)
)
IF not defined STOP goto LOOP


So as you can see the for loop itself is not infinite, But there is only one goto per 300 loops (or as many as you choose).

I think einstein1969 posted this first.

I have seen one made by jeb that uses goto:eof
I don't quite know if goto:eof is slower than regular goto label but surely your answer is useful.
Gonna give it a try too. :D

NunoLava1998
Posts: 10
Joined: 01 Mar 2015 10:06

Re: How to speed up a batch script

#13 Post by NunoLava1998 » 30 Dec 2016 04:34

As of i know, a single batch command takes exactly 1 millisecond to execute.

This is proven when you do:

Code: Select all

echo 1
echo 2
echo 3
...
echo 999
echo 1000

that it takes 1 second to finish.

aGerman
Expert
Posts: 4654
Joined: 22 Jan 2010 18:01
Location: Germany

Re: How to speed up a batch script

#14 Post by aGerman » 30 Dec 2016 05:25

NunoLava1998 wrote:As of i know, a single batch command takes exactly 1 millisecond to execute.

No. Try
>nul echo 1
etc.

and try
cmd /c echo 1
etc.

While the first should be faster because it doesn't output to the screen (and thus, doesn't invoke screen updating) the second is certainly a hundred times slower because the OS has to schedule a new process each.

Also 1ms may be true on your PC under certain conditions. It highly depends on the speed of your CPU, current CPU use, installed RAM, current memory availability, etc.

Steffen

misol101
Posts: 475
Joined: 02 May 2016 18:20

Re: How to speed up a batch script

#15 Post by misol101 » 30 Dec 2016 06:59

Another little speedup trick is to clear out all or almost all unused environment variables. I found that all my scripts got a 5-10% speedup by doing this. I found this trick in a script by einstein1969. Just remember to call setlocal first, otherwise the variables are deleted from your actual cmd envioronment.

Code: Select all

setlocal
for /F "tokens=1 delims==" %%v in ('set') do set "%%v="
...
endlocal

Note that this will clear all variables, including the PATH. This works as long as you don't call any external programs, OR the external programs are either in your current folder OR they are called with absolute paths.

You could also easily keep one or more variables that you need, like PATH, by doing:

Code: Select all

for /F "tokens=1 delims==" %%v in ('set') do if /I not "%%v"=="PATH" set "%%v="

Post Reply