Board index » cppbuilder » Very slow WideString in C++ Builder 2007

Very slow WideString in C++ Builder 2007


2008-01-02 09:16:07 PM
cppbuilder81
Hi.
We have run into a problem with our software after changing development
platform from Borland C++ Builder 6 to Codegear C++ Builder 2007...
I found that WideString handling is much slower in C++ Builder 2007. Here
you can download a
simple example program (including source) compiled on both platforms:
www.edialog24.com/tmp/widestringtest/widestring-example.zip
This is what the program does:
1) Load a 100 KB text-file from harddrive into the WideString-variable
txtWideString.
2) Run this code:
for(int i=1;i<40000;i++)
{
if(txtWideString.Length()>i&&txtWideString[i]==L'>')
{
int j = 0;
}
}
The program compiled with C++ Builder 6 runs in no time at all, while the
program compiled with C++ Builder 2007 needs about 9 seconds (on my
computer) to finish the exact same code. Is this a known bug?
Regards,
Christian Myksvoll.
 
 

Re:Very slow WideString in C++ Builder 2007

Hello,
the culprit seems to be WideString::Length(). If I change the code to
int len = txtWideString.Length();
for(int i=1;i<40000;i++)
{
if(len>i&&txtWideString[i]==L'>')
{
int j = 0;
}
}
then it works as fast as the AnsiString code.
Compiling the code with C++Builder 2006 gives the same results as with
C++Builder 2007.
I haven't found a report for it in QC (searched for keyword
"WideString"). So it doesn't seem to be a known bug.
Regards
Hans
Christian Myksvoll wrote:
Quote
Hi.
We have run into a problem with our software after changing development
platform from Borland C++ Builder 6 to Codegear C++ Builder 2007...
I found that WideString handling is much slower in C++ Builder 2007. Here
you can download a
simple example program (including source) compiled on both platforms:
www.edialog24.com/tmp/widestringtest/widestring-example.zip


This is what the program does:
1) Load a 100 KB text-file from harddrive into the WideString-variable
txtWideString.
2) Run this code:

for(int i=1;i<40000;i++)
{
if(txtWideString.Length()>i&&txtWideString[i]==L'>')
{
int j = 0;
}
}

The program compiled with C++ Builder 6 runs in no time at all, while the
program compiled with C++ Builder 2007 needs about 9 seconds (on my
computer) to finish the exact same code. Is this a known bug?

Regards,
Christian Myksvoll.



 

Re:Very slow WideString in C++ Builder 2007

If you create a QC report for this, then it can be promoted to CodeGear's
internal database.
It looks like a compiler optimisation so you might want to check compiler
switches first which I believe may have changed.
Thanks, Pete
"Johannes Weinert" < XXXX@XXXXX.COM >wrote in message
Quote
Hello,

the culprit seems to be WideString::Length(). If I change the code to

int len = txtWideString.Length();
for(int i=1;i<40000;i++)
{
if(len>i&&txtWideString[i]==L'>')
{
int j = 0;
}
}

then it works as fast as the AnsiString code.

Compiling the code with C++Builder 2006 gives the same results as with
C++Builder 2007.

I haven't found a report for it in QC (searched for keyword "WideString").
So it doesn't seem to be a known bug.

Regards

Hans

Christian Myksvoll wrote:
>Hi.
>We have run into a problem with our software after changing development
>platform from Borland C++ Builder 6 to Codegear C++ Builder 2007...
>I found that WideString handling is much slower in C++ Builder 2007. Here
>you can download a
>simple example program (including source) compiled on both platforms:
>www.edialog24.com/tmp/widestringtest/widestring-example.zip
>
>
>This is what the program does:
>1) Load a 100 KB text-file from harddrive into the WideString-variable
>txtWideString.
>2) Run this code:
>
>for(int i=1;i<40000;i++)
>{
>if(txtWideString.Length()>i&&txtWideString[i]==L'>')
>{
>int j = 0;
>}
>}
 

{smallsort}

Re:Very slow WideString in C++ Builder 2007

In BCB6 the WideString::Length() method called the Pascal function
System.WStrLen(). In BDS2006 WideString::Length() calls
Strhlpr::WideLength() which then calls System.WStrLen(). An extra
redirection shouldn't cause 9 seconds of delay so I created a temporary
application and stepped through the calls. When I looked at the CPU view
WideString::Length() copy-constructs a temporary WideString, calls
Strhlpr::WideLength(), then destroys the temporary WideString. The
assembler code for WStrLen() is the same as the BCB6 version so the culprit
must be the construction, destruction, in addition to the extra redirection.
I believe the extra construction/destruction is caused by the fact that
WideString::Length() is a const method which makes WideString be a "const"
object. I created the following test to verify this idea. In BCB6 I added
the following function to a PAS file:
function WideLength(const str : WideString) : Integer;
begin
Result := Length(str); // calls WStrLen
end;
And then in my CPP file I called it two ways:
WideString str1;
WideLength(str1); // No const/dest in CPU view
WideString const str2;
WideLength(str2); // Const/dest in CPU view
The 'str2' test represents the call from BDS2006's WideString::Length()
method.
CodeGear can fix this problem in one of two ways.
1) Change WideString::Length() back to the BCB6 code -- call WStrLen()
directly
2) Modify WideString::Length() to call Strhlpr::WideLength() like this:
return Strhlpr::WideLength(*const_cast <WideString*>(this));
There is a third option but it would be to fix the compiler to identify that
the call to Strhlpr::WideLength() requires a const reference and that it is
safe to pass the "this" argument rather than copy-constructing a temporary
first. I'm not sure of the ramifactions of that though.
Clayton
 

Re:Very slow WideString in C++ Builder 2007

"Clayton Arends" < XXXX@XXXXX.COM >wrote in message
Quote
the culprit must be the construction, destruction, in addition to
the extra redirection.
WideString is not reference counted like AnsiString is (UnicodeString in the
next version of of the VCL will be, though). Constructing a WideString from
an existing string (whether AnsiString, WideString, char*, or wchar_t*)
requires a new memory block to be allocated and the characters then copied
into it.
Gambit
 

Re:Very slow WideString in C++ Builder 2007

"Clayton Arends" < XXXX@XXXXX.COM >wrote in message
Quote
When I looked at the CPU view WideString::Length() copy-constructs
a temporary WideString, calls Strhlpr::WideLength(), then destroys the
temporary WideString.
Please report this to QC so it can be promoted to CodeGear's internal
system.
Gambit
 

Re:Very slow WideString in C++ Builder 2007

"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >wrote in message
Quote
Please report this to QC so it can be promoted to CodeGear's internal
system.
Nevermind, I have posted a report for you - QC #56540. RAID is not
responding right now.
Gambit
 

Re:Very slow WideString in C++ Builder 2007

"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >wrote in message
Quote
Nevermind, I have posted a report for you - QC #56540.
Thanks Remy. The report looks good.
Clayton