while I try to build a small batch list selection component for a customer, I stumbled about the horrible, poor performance of batch functions on network drives.
My code used the standard :strlen function 180 times and it takes some seconds.
I decided to use a strlen macro, it's faster, but still not satisfying, so I checked the performance killers.
Mac1
Code: Select all
(set ^"$\n=^^^
%= This creates an escaped Line Feed - DO NOT ALTER =%
)
set $strLen=for %%# in (1 2) do if %%#==2 ( %$\n%
for /f "tokens=1,2 delims=, " %%1 in ("!argv!") do ( %$\n%
%= *** remove the local variable "argv" =% %$\n%
endlocal %$\n%
%= *** copy content to temporary variable, the carets are for extended length, up to 8191chars =% %$\n%
(set^^ s=!%%~2!) %$\n%
if defined s ( %$\n%
set "len=1" %$\n%
for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do ( %$\n%
if "!s:~%%P,1!" neq "" ( %$\n%
set /a "len+=%%P" %$\n%
set "s=!s:~%%P!" %$\n%
) %$\n%
) %$\n%
) ELSE set "len=0" %$\n%
for %%V in (!len!) do endlocal ^& set "%%~1=%%V" %$\n%
) %$\n%
) else setlocal EnableDelayedExpansion ^& setlocal ^& set argv=,
Mac2 Removing one pair was easy, as the inner pair is only for the argv variable.
Mac3 Removing the last setlocal EnableDelayedExpansion makes the macro nearly three times faster than before, but this has two drawbacks.
1. There are now three variables polluting the environment (can be optimized to two variables)
2. The macro only works if EnableDelayedExpansion was already active
Code: Select all
Macro | DDE | EDE
-------------------
Mac1 | 6370 | 6370
Mac2 | 4700 | 4700
Mac3 | fail | 2600
Mac4 | 4700 | 2600
Mac5 | 4800 | 2700
But it should enable delayed expansion only when necessary.
Mac4
Here is the trick to get the current state and store it in a for meta variable with:
Code: Select all
for /F "tokens=2" %%E in ("!! D """) DO
This can be uses in an IF statement or just another FOR
Code: Select all
( for %%X in (%%~E) DO setlocal EnableDelayedExpansion)
Mac5
Code: Select all
(set ^"$\n=^^^
%= This creates an escaped Line Feed - DO NOT ALTER =%
)
set $strLen=for /F "tokens=2" %%E in ("!! D """) DO for %%# in (1 2) do if %%#==2 ( %$\n%
for /f "tokens=1,2 delims=, " %%1 in ("!_!") do ( %$\n%
%= *** copy content to temporary variable, the carets are for extended length, up to 8191chars =% %$\n%
(set^^ _=!%%~2!) %$\n%
if defined _ ( %$\n%
set "_len=1" %$\n%
for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do ( %$\n%
if "!_:~%%P,1!" neq "" ( %$\n%
set /a "_len+=%%P" %$\n%
set "_=!_:~%%P!" %$\n%
) %$\n%
) %$\n%
) ELSE set "_len=0" %$\n%
for %%V in (!_len!) do ( for %%E in (%%~E) DO endlocal ) ^& set "%%~1=%%V" %$\n%
) %$\n%
) else ( for %%E in (%%~E) DO setlocal EnableDelayedExpansion) ^& set _=,