Page 1 of 1

strlen questions

Posted: 03 Apr 2013 05:42
by Sponge Belly
Hi Jeb!

You answered this SO question in May, 2012. Your code for StrLen was as follows:

Code: Select all

(   
    setlocal EnableDelayedExpansion
    set "s=!%~2!#"
    set "len=0"
    for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
        if "!s:~%%P,1!" NEQ "" (
            set /a "len+=%%P"
            set "s=!s:~%%P!"
        )
    )
)
(
    endlocal
    set "%~1=%len%"
    exit /b
)


And then you said…

The first parenthesis blocks is only for a bit more performance.


Please expand on that remark. How does the presence of parentheses affect performance? Is there a rule of thumb for when a programmer should or should not enclose a block in parentheses?

Lastly, is the above code the “definitive” version of StrLen? There are a lot of variants floating around and I’m not sure which one to use. :?:

- SB

Re: strlen questions

Posted: 03 Apr 2013 08:10
by Endoro
Hi, here are performance measurements of strlen functions: strlen

Re: strlen questions

Posted: 03 Apr 2013 10:54
by jeb
Another good thread about optimized strlen functions is also at dostips strLen boosted started by sowgtsoi.

One of the fastest methods to get the strlen is not a function, it's a macro.

Code: Select all

@echo off
call :loadMacros
set "myVar=abcdefg"
%$strlen%  result myVar
echo %result%
exit /b


:loadMacros
set LF=^


::Above 2 blank lines are required - do not remove
set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
:::: StrLen pResult pString
set $strLen=for /L %%n in (1 1 2) do if %%n==2 (%\n%
      for /F "tokens=1,2 delims=, " %%1 in ("!argv!") do (%\n%
         set "str=A!%%~2!"%\n%
           set "len=0"%\n%
           for /l %%A in (12,-1,0) do (%\n%
            set /a "len|=1<<%%A"%\n%
            for %%B in (!len!) do if "!str:~%%B,1!"=="" set /a "len&=~1<<%%A"%\n%
           )%\n%
           for %%v in (!len!) do endlocal^&if "%%~b" neq "" (set "%%~1=%%v") else echo %%v%\n%
      ) %\n%
) ELSE setlocal enableDelayedExpansion ^& set argv=,

exit /b

The macro technic is also explained somewhere here :)

But to your question
Sponge Belly wrote:Quote:
The first parenthesis blocks is only for a bit more performance.

Please expand on that remark. How does the presence of parentheses affect performance? Is there a rule of thumb for when a programmer should or should not enclose a block in parentheses?

A parenthesis block is mostly a bit faster, as it's completly parsed and cached before it's executed.

And to you last question
Sponge Belly wrote:Lastly, is the above code the “definitive” version of StrLen? There are a lot of variants floating around and I’m not sure which one to use. :?:

No, there isn't a definitive version, a good version for short strings can be slow for long strings, or another version depends on the disk speed.
But a good version should be able to handle long strings up to 8190 characters.
And it should be exact and independent for any possible character in the string.

jeb

Re: strlen questions

Posted: 03 Apr 2013 15:00
by Sponge Belly
@Endoro

Thanks for the link, but I had recently discovered it myself. I’m surprised Dave Benham hasn’t reposted his answer here…

@Jeb

A parenthesis block is mostly a bit faster, as it's completly parsed and cached before it's executed.


I never knew that! :shock: Let me rephrase that… I never realised that before. These things have to be spelt out for me. Too much Bushmills in my formative years. Everyone else was drinking Guinness, but no! I had to be different…

Anyways, thanks for that and thanks also for reposting the macro version of StrLen. I’m not ready for macros yet. Whenever I try to read macro code, my brain starts to ache and I remember why I stopped drinking whiskey. ;-)

- SB