Delphi Clinic C++Builder Gate Training & Consultancy Delphi Notes Weblog Dr.Bob's Webshop
Bob Swart (aka Drs.Bob) Dr.Bob's Delphi Clinics Dr.Bob's Delphi Courseware Manuals
View Bob Swart's profile on LinkedIn Drs.Bob's Delphi Notes
These are the voyages using Delphi Enterprise (and Architect). Its mission: to explore strange, new worlds. To design and build new applications. To boldly go...
Title:

Delphi 2009 Implicit String Conversion Penalties

Author: Bob Swart
Posted: 4/16/2009 12:30:00 PM (GMT+1)
Content:

When migrating existing source code from previous versions of Delphi to Delphi 2009, you may encounter warnings about implicit conversions from AnsiString to Unicode Strings or vice versa (the other way may also have a potential data loss) and while it's easy to ignore these warnings, ignorance comes with a price!

The particular real-world example I want to talk about in this post comes from a third-party library (who shall remain nameless) compatible with different versions of Delphi, including Delphi 2009. When I migrated my project from Delphi 2007 to Delphi 2009, the resulting application worked fine except when calling the third-party routine to perform a certain task. Response times went up from 2 seconds to almost 20 minutes (I'm not joking), which is a long time to wait for an answer to be formulated.

By the way, originally we thought the process was just hanging, until I allowed it to continue to run and it came back with an answer 20 minutes later. At that point, I made sure to add the source code of the third-party library to my search path, and started to step into the third-party source code. Doing so, caused the compiler to show a number of hints and warnings (that were obviously not fixed in this library), mainly concerning the Ansi vs. Unicode strings and implicit conversions. Warnings that could be skipped - or so the original developers thought.

One of the tasks this code was doing, involved writing a series of hexadecimal values to a stream, and it did this by adding them to a local string variable. The local string variable was of type AnsiString, and the loop was coded as follows (slightly altered to protect the innocent):

  for i:=0 to LongList.Count-1 do
begin

LocalAnsiString := LocalAnsiString +
'<' + IntToHex(Integer(LongList.Items[i]), 4) +
'> <' + IntToHex(Integer(LongList.Items[i]), 4) + '> ' +
IntToStr(Integer(LongList.Items[i])) + CRLF;
end;

The LocalAnsiString is an AnsiString, and the parts that are added are Unicode Strings (especially the result of the IntToHex function) which need to be converted to AnsiStrings. This happened all over the place in this third-party library, and is usually no big deal, unless you're doing it in a loop for more than 38 thousand items (with a string growing to half a megabyte in size).

I've managed to make the application several times faster (going from 20 minutes to 2 seconds again - not just for the loop) by adding a single cast:
  for i:=0 to LongList.Count-1 do
begin

LocalAnsiString := LocalAnsiString + AnsiString( // BS
'<' + IntToHex(Integer(LongList.Items[i]), 4) +
'> <' + IntToHex(Integer(LongList.Items[i]), 4) + '> ' +
IntToStr(Integer(LongList.Items[i])) + CRLF);
end;

That way, only one - explicit - conversion of Unicode to AnsiString will happen instead of implicit ones (originally probably casting the LocalAnsiString up to a Unicode String first, then perform all the string additions and casting the result back to an AnsiString which will become slower and slower when the string content grows). Note that this single change will still compile with older versions of Delphi, and no longer produces a warning using Delphi 2009. Or loss of speed.

Needless to say, I sent the original author of this third-party library a friendly suggestion to compile the code with Delphi 2009 and try to fix all warnings, especially concerning the (Unicode)String to AnsiString issues.
They were pleased with my findings, and quickly updated their code.

Back  


4 Comments

AuthorPostedComments
Thaddy 09/04/16 15:52:03We always treat warnings as errors.... Cheers Bob, you know what to do with that ;)
Bob Swart 09/04/16 16:33:00This post can now also be read at http://ebob42.ulitzer.com/
Dan 10/04/12 16:34:26Hi Bob, this static typecast has solved the problem of speed performance but what about the data loss when converting from Unicode string to AnsiString. That static cast will solve that too or is there a way around? thanx for your articles. Dan.
the best seo service 13/09/06 14:06:28Li7aBB Major thanks for the post.Really looking forward to read more. Really Cool.


New Comment (max. 2048 characters, no HTML):

Name:
Comment:



This webpage © 2005-2014 by Bob Swart (aka Dr.Bob - www.drbob42.com). All Rights Reserved.