[fpc-pascal] Re: UnicodeString comparison performance

OBones obones at free.fr
Tue Jul 24 13:21:52 CEST 2012

Thomas Schatzl wrote:
> This code is not thread safe at all. A thread switch after the while
> loop and before the increment will not prevent progress on other
> threads, so multiple threads can enter the "critical section".
Well, yes, even if under Windows it's rare that a thread is preempted 
right in the middle of its execution. At least that's what my own 
experience has told me and why I'm calling Sleep in the while loop, so 
that the thread yields to other ones.

> Use EnterCriticalSection/LeaveCriticalSection from the RTL if you need
> that.
I did not because I thought that would be too slow, but it turns out 
it's not so yes, it's much better.

> If you could somewhat decrease the size of your buffer to something
> reasonable - do you really expect to translate a string with 1M chars? -
> use the stack. Actually even a 2M data object on the stack might be
> reasonable.
That's the highest value that the documentation of the API is giving, so 
I guess the API will respect its own publicized contract.

> function GetSomeString(index : integer) : UnicodeString;
> const
>    bufsize = 1024; // as you wish
> var
>    buffer : array[0..bufsize-1] of WideChar;
>    pbuffer : PWideChar;
>    islongstring : boolean;
>    lengthofstring : integer;
> begin
>    lengthofstring := length(stringfromindex(integer));
>    islongstring := lengthofstring > bufsize;
>    if (islongstring) then
>      pbuffer := getmem(lengthofstring * sizeof(WideChar));
>    else
>      pbuffer := @buffer;
>    CallToAnAPIThatWritesBackAWideString(stringfromindex(integer),
> pbuffer, lengthofstring);
>    if (islongstring) then
>      freemem(pbuffer);
>    result := pbuffer;
> end;
Thanks for your example, but it implies that the string length is known 
before calling the API while this is not the case.
The API is given a buffer and a maximum length, a buffer into which it 
writes a zero terminated string. But the length of that string cannot be 
known beforehand, hence the reason why I wrote it that way.
Note also that having buffer local to the function is just as bad 
(performance wise) as setting the length of the result string.

In the end, many thanks for your suggestions, I'll go with the critical 
section as it is much safer.


More information about the fpc-pascal mailing list