Oct 8, 2013

Batch code variants: GenerateDrivePolicyValue

Below I present code variants of the GenerateDrivePolicyValue procedure. They result in the same and utilize the same method, but differ if about performance. All the performance comparisons regard execution in Windows 7.

The slowest variant:
:GenerateDrivePolicyValue
set alphabet=A;B;C;D;E;F;G;H;I;J;K;L;M;N;O;P;Q;R;S;T;U;V;W;X;Y;Z
set init=1
for %%A in (%alphabet%) do (for /f "tokens=2 delims=^=" %%B in ('set init') do (set Drive%%A=%%B;0&set/a init*=2))
set init=
set final=0
for %%A in (%*) do (for %%B in (%alphabet%) do (if "%%A"=="%%B:" (call:RaiseValBy %%B||echo  Drive '%%B:' has already been added)))
for %%A in (%alphabet%) do (set Drive%%A=&if defined IsAlready%%A (set IsAlready%%A=))
set alphabet=
call:ThrowErrorLevel %final%
exit/b%errorlevel%
:ThrowErrorLevel
set final=
exit/b%1
:RaiseValBy
for /f "tokens=2,3 delims=^=;" %%A in ('set Drive%1') do (
 if "%%B"=="1" (
  exit/b1
 ) else (
  for /f "tokens=2 delims=^=" %%C in ('set final') do (
  set/a final=%%C+%%A
  set Drive%1=%%A;1
  )
 )
)
exit/b0


A bit faster one:
:GenerateDrivePolicyValue
set alphabet=A;B;C;D;E;F;G;H;I;J;K;L;M;N;O;P;Q;R;S;T;U;V;W;X;Y;Z
set init=1
for %%A in (%alphabet%) do (for /f "tokens=2 delims=^=" %%B in ('set init') do (set Drive%%A=%%B&set/a init*=2))
set init=
set final=0
for %%A in (%*) do (for %%B in (%alphabet%) do (if "%%A"=="%%B:" (call:RaiseValBy %%B)))
for %%A in (%alphabet%) do (set Drive%%A=&if defined IsAlready%%A (set IsAlready%%A=))
set alphabet=
call:ThrowErrorLevel %final%
exit/b%errorlevel%
:ThrowErrorLevel
set final=
exit/b%1
:RaiseValBy
if not defined Drive%1 (exit/b0)
for /f "tokens=2 delims=^=" %%A in ('set Drive%1') do set val=%%A
set/a final=%final%+%val%
set Drive%1=
exit/b0


And the fastest of the three:
:GenerateDrivePolicyValue
setlocal
set alphabet=A;B;C;D;E;F;G;H;I;J;K;L;M;N;O;P;Q;R;S;T;U;V;W;X;Y;Z
set init=1
for %%A in (%alphabet%) do (call:LoadArrayProc %%A)
for %%A in (%*) do (for %%B in (%alphabet%) do (if "%%A"=="%%B:" (call:RaiseValBy %%B %%Drive%%B%%)))
endlocal&exit/b%final%
:LoadArrayProc
set Drive%1=%init%&set/a init*=2&exit/b0
:RaiseValBy
if not "%2"=="" (set/a final=%final%+%2)
exit/b0

Update: I forgot to add the variant that is used in GTweak, my now-discontinued project. Performance of this one has not been tested.
:GenerateDrivePolicyValue
set alphabet=A;B;C;D;E;F;G;H;I;J;K;L;M;N;O;P;Q;R;S;T;U;V;W;X;Y;Z
set init=1
for %%A in (%alphabet%) do (call:LoadArrayProc %%A)
set init=
for %%A in (%*) do (for %%B in (%alphabet%) do (if "%%A"=="%%B:" (call:RaiseValBy %%B||echo  Drive '%%B:' has already been added)))
for %%A in (%alphabet%) do (set Drive%%A=&if defined IsAlready%%A (set IsAlready%%A=))
set alphabet=
call:ThrowErrorLevel %final%
exit/b%errorlevel%
:ThrowErrorLevel
set final=
exit/b%1
:LoadArrayProc
set Drive%1=%init%&set/a init*=2&exit/b0
:RaiseValBy
set var1=%% IsAlready%1 %%
set var1=%var1: =%
for %%A in (%var1%) do (call:RaiseValBy_1 %%A||exit/b1)
set var2=%% Drive%1 %%
set var2=%var2: =%
call set/a final=%final%+%var2%
set IsAlready%1=1
set var2=&set var1=
exit/b0
:RaiseValBy_1
if "%1"=="1" (exit/b1) else (exit/b0)

...and this is the very first variant of what I was about to name "GenerateDrivePolicyValue" and improve later. This one comes from GTweak 1.35, released in December 2010. Its performance is also uncertain, though, from what I so far have seen, it could conquer the newest, thinnest variant. Go and give it a try if you care. :)
@echo off
:loop
echo.
setlocal
for %%A in (A: B: C: D: E: F: G: H: I: J: K: L: M: N: O: P: Q: R: S: T: U: V: W: X: Y: Z:) do call:mgrdrvloop %%A
endlocal&echo.&echo %final%
pause
goto loop
:mgrdrvloop
::echo.
::set/p ch= Type drive letter ^> 
::if /i "%1"=="discard" set final=0
::if /i "%1"=="give_up" goto oep
::if /i "%1"=="nothing" set final=0&&exit/b0
::if /i "%1"=="done" exit/b0
::if /i "%1"=="all" set final=67108863&&echo  All drives added&&exit/b0
if "%1"=="A:" if not "%IsAlreadyA%"=="1" set /a final=%final%+1&&set IsAlreadyA=1&&exit/b0
if "%1"=="B:" if not "%IsAlreadyB%"=="1" set /a final=%final%+2&&set IsAlreadyB=1&&exit/b0
if "%1"=="C:" if not "%IsAlreadyC%"=="1" set /a final=%final%+4&&set IsAlreadyC=1&&exit/b0
if "%1"=="D:" if not "%IsAlreadyD%"=="1" set /a final=%final%+8&&set IsAlreadyD=1&&exit/b0
if "%1"=="E:" if not "%IsAlreadyE%"=="1" set /a final=%final%+16&&set IsAlreadyE=1&&exit/b0
if "%1"=="F:" if not "%IsAlreadyF%"=="1" set /a final=%final%+32&&set IsAlreadyF=1&&exit/b0
if "%1"=="G:" if not "%IsAlreadyG%"=="1" set /a final=%final%+64&&set IsAlreadyG=1&&exit/b0
if "%1"=="H:" if not "%IsAlreadyH%"=="1" set /a final=%final%+128&&set IsAlreadyH=1&&exit/b0
if "%1"=="I:" if not "%IsAlreadyI%"=="1" set /a final=%final%+256&&set IsAlreadyI=1&&exit/b0
if "%1"=="J:" if not "%IsAlreadyJ%"=="1" set /a final=%final%+512&&set IsAlreadyJ=1&&exit/b0
if "%1"=="K:" if not "%IsAlreadyK%"=="1" set /a final=%final%+1024&&set IsAlreadyK=1&&exit/b0
if "%1"=="L:" if not "%IsAlreadyL%"=="1" set /a final=%final%+2048&&set IsAlreadyL=1&&exit/b0
if "%1"=="M:" if not "%IsAlreadyM%"=="1" set /a final=%final%+4096&&set IsAlreadyM=1&&exit/b0
if "%1"=="N:" if not "%IsAlreadyN%"=="1" set /a final=%final%+8192&&set IsAlreadyN=1&&exit/b0
if "%1"=="O:" if not "%IsAlreadyO%"=="1" set /a final=%final%+16384&&set IsAlreadyO=1&&exit/b0
if "%1"=="P:" if not "%IsAlreadyP%"=="1" set /a final=%final%+32768&&set IsAlreadyP=1&&exit/b0
if "%1"=="Q:" if not "%IsAlreadyQ%"=="1" set /a final=%final%+65536&&set IsAlreadyQ=1&&exit/b0
if "%1"=="R:" if not "%IsAlreadyR%"=="1" set /a final=%final%+131072&&set IsAlreadyR=1&&exit/b0
if "%1"=="S:" if not "%IsAlreadyS%"=="1" set /a final=%final%+262144&&set IsAlreadyS=1&&exit/b0
if "%1"=="T:" if not "%IsAlreadyT%"=="1" set /a final=%final%+524288&&set IsAlreadyT=1&&exit/b0
if "%1"=="U:" if not "%IsAlreadyU%"=="1" set /a final=%final%+1048576&&set IsAlreadyU=1&&exit/b0
if "%1"=="V:" if not "%IsAlreadyV%"=="1" set /a final=%final%+2097152&&set IsAlreadyV=1&&exit/b0
if "%1"=="W:" if not "%IsAlreadyW%"=="1" set /a final=%final%+4194304&&set IsAlreadyW=1&&exit/b0
if "%1"=="X:" if not "%IsAlreadyX%"=="1" set /a final=%final%+8388608&&set IsAlreadyX=1&&exit/b0
if "%1"=="Y:" if not "%IsAlreadyY%"=="1" set /a final=%final%+16777216&&set IsAlreadyY=1&&exit/b0
if "%1"=="Z:" if not "%IsAlreadyZ%"=="1" set /a final=%final%+33554432&&set IsAlreadyZ=1&&exit/b0
echo.
echo  Input '%1' is not a valid drive letter OR drive already added
exit/b1

No comments:

Post a Comment