For a
Pascal String in case that the reserved Memory is bigger than the actually written content with the
SetLength() Procedure I found that it is useful to use the
#0 Character to limit the written Sequence and the
strlen() to find the actually usable string.
I found this especially when working with the
TStringStreamNow on big strings this can result in some performance loss.
But thinking of this Documentation:
https://www.man7.org/linux/man-pages/man3/memchr.3.htmlI was wondering if the
IndexByte() Function could be useful to write a faster
strlen() Function just like in this Example:
The following call is a fast means of locating a string's terminating null byte:
char *p = rawmemchr(s, '\0');
So I developed this little Function:
{$IFOPT D+}
{$NOTE debug mode is active. disabling inline}
{$DEFINE debug_on}
{$ENDIF}
function PCharLength(const ssource: PChar): Cardinal; {$IFNDEF debug_on} inline; {$ENDIF}
var
pssrc: PChar;
imtchps: Integer;
isrhrng: Cardinal;
begin
Result := 0;
pssrc := ssource;
isrhrng := 1024;
repeat //until imtchps <> -1;
imtchps := IndexByte(pssrc^, isrhrng, 0);
if imtchps = -1 then
begin
inc(Result, isrhrng);
inc(pssrc, isrhrng);
isrhrng := isrhrng * 2;
end; //if imtchps = -1 then
until imtchps <> -1;
inc(Result, imtchps);
end;
I made a little benchmark to see if there is any measurable improvement:
-------
Big Source 1 (length: '33044') - strlen (count: '1000') - Start - Now in millisecs since midnight : 44566167
Big Source 1 - strlen - End - Now in millisecs since midnight : 44566191
Big Source 1: strlen completed in '23.9996938034892' ms.
Big Source 1 (length: '33044') - PCharLength (count: '1000') - Start - Now in millisecs since midnight : 44566191
Big Source 1 - PCharLength - End - Now in millisecs since midnight : 44566212
Big Source 1: PCharLength completed in '21.0004393011332' ms.
-------
Big Source 1 (length: '66088') - strlen (count: '1000') - Start - Now in millisecs since midnight : 44566212
Big Source 1 - strlen - End - Now in millisecs since midnight : 44566250
Big Source 1: strlen completed in '37.9995675757527' ms.
Big Source 1 (length: '66088') - PCharLength (count: '1000') - Start - Now in millisecs since midnight : 44566250
Big Source 1 - PCharLength - End - Now in millisecs since midnight : 44566283
Big Source 1: PCharLength completed in '32.9999718815088' ms.
In strings
> 32KB you can notice an advantage of
2 - 3 ms on
1000 Operationsand on strings
> 64 KB you can observe an advantage of
3 - 5 ms on
1000 Operations