Page 1 of 1

SET/A and Exclamation mark expand

Posted: 26 May 2014 06:49
by einstein1969
Hi to all,

I have a problem with performance tuning a code that use SET /A instructions.

I have discoverer that the using the exclamation mark (in certain cases?) is faster than without.

Can any expert explain why this istruction:

Code: Select all

set /a aa=!p[%%i].a!, bb=!p[%%i].b!, cc=!p[%%i].c!


is faster than:

Code: Select all

set /a aa=p[%%i].a, bb=p[%%i].b, cc=p[%%i].c

:?:


this is the code that test the time elapsed in centisecond:

Code: Select all

@echo off & setlocal EnableDelayedExpansion

For /L %%i in (1,1,100) do set /a "p[%%i].a=!random! %% 100, p[%%i].b=!random! %% 100, p[%%i].c=!random! %% 100"


set t0=!time!
for /L %%N in (1,1,300) do (

  For /L %%i in (1,1,100) do set /a aa=!p[%%i].a!, bb=!p[%%i].b!, cc=!p[%%i].c!

)
set t1=!time!
call :difftime

set t0=!time!
for /L %%N in (1,1,300) do (

  For /L %%i in (1,1,100) do set /a aa=p[%%i].a, bb=p[%%i].b, cc=p[%%i].c

)
set t1=!time!
call :difftime

endlocal & goto :eof


:difftime
  for /F "tokens=1-8 delims=:.," %%a in ("!t0: =0!:!t1: =0!") do set /a "a=(((1%%e-1%%a)*60)+1%%f-1%%b)*6000+1%%g%%h-1%%c%%d, a+=(a>>31) & 8640000"
  echo !a! cs
goto :eof


my results:

Code: Select all

533 cs
829 cs

einstein1969

Re: SET/A and Exclamation mark expand

Posted: 26 May 2014 07:35
by Aacini
This result is strange. I can only guess that the method that the parser uses to locate and expand a !variable! is more efficient than the same method used in SET /A command...

Antonio

Re: SET/A and Exclamation mark expand

Posted: 26 May 2014 10:07
by einstein1969
Yes, strange... :?

But i have semplified the example and in the set /a have removed the %%i variable.

From:

Code: Select all

set /a aa=!p[%%i].a!, bb=!p[%%i].b!, cc=!p[%%i].c!



to code:

Code: Select all

set /a aa=!p[100].a!, bb=!p[100].b!, cc=!p[100].c!


I have duobled the number of variable from 100 to 200. And the number 100 is the half, is in the middle.

I have retest:

Code: Select all

setlocal EnableDelayedExpansion

For /L %%i in (1,1,200) do set /a "p[%%i].a=!random! %% 100, p[%%i].b=!random! %% 100, p[%%i].c=!random! %% 100"


set t0=!time!

for /L %%N in (1,1,100) do (

  For /L %%i in (1,1,200) do set /a aa=!p[100].a!, bb=!p[100].b!, cc=!p[100].c!

)


set t1=!time!
call :difftime

set /a a1=a

set t0=!time!

for /L %%N in (1,1,100) do (

  For /L %%i in (1,1,200) do set /a aa=p[100].a, bb=p[100].b, cc=p[100].c

)

set t1=!time!
call :difftime

set /a a2=a, ratio=a2*100/a1-100

echo Ratio=+%ratio%%%

endlocal


the result is:

Code: Select all

618 cs
548 cs
Ratio=+-12%


this result is not the most strange and come back the way you would expect. Now the !expand! is slower... :D

but....

I have probed for element 99:

Code: Select all

set /a aa=!p[99].a!, bb=!p[99].b!, cc=!p[99].c!


and the result is more stranger!!!

result:

Code: Select all

859 cs
1467 cs
Ratio=+70%


:shock: :?

the extract code of last test:

Code: Select all

setlocal EnableDelayedExpansion

For /L %%i in (1,1,200) do set /a "p[%%i].a=!random! %% 100, p[%%i].b=!random! %% 100, p[%%i].c=!random! %% 100"


set t0=!time!

for /L %%N in (1,1,100) do (

  For /L %%i in (1,1,200) do set /a aa=!p[99].a!, bb=!p[99].b!, cc=!p[99].c!

)


set t1=!time!
call :difftime

set /a a1=a

set t0=!time!

for /L %%N in (1,1,100) do (

  For /L %%i in (1,1,200) do set /a aa=p[99].a, bb=p[99].b, cc=p[99].c

)

set t1=!time!
call :difftime

set /a a2=a, ratio=a2*100/a1-100

echo Ratio=+%ratio%%%

endlocal



einstein1969