<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Delphi 2009 &#8211; String Performance</title>
	<atom:link href="http://www.deltics.co.nz/blog/Index.php?feed=rss2&#038;p=349" rel="self" type="application/rss+xml" />
	<link>http://www.deltics.co.nz/blog/?p=349</link>
	<description>Keeping Delphi afloat in Aotearoa</description>
	<lastBuildDate>Fri, 03 Sep 2010 13:44:08 +1200</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Don&#8217;t Get Hung Up on Milliseconds - Micro-ISV.asia</title>
		<link>http://www.deltics.co.nz/blog/?p=349&#038;cpage=1#comment-387</link>
		<dc:creator>Don&#8217;t Get Hung Up on Milliseconds - Micro-ISV.asia</dc:creator>
		<pubDate>Mon, 06 Oct 2008 09:37:00 +0000</pubDate>
		<guid isPermaLink="false">http://www.deltics.co.nz/blog/?p=349#comment-387</guid>
		<description>[...] Smith posted a comment to one of my previous articles with a link to his own Delphi 2009 String Performance article. (By the way: I&#8217;m cool with people posting comments mentioning their own posts, if [...]</description>
		<content:encoded><![CDATA[<p>[...] Smith posted a comment to one of my previous articles with a link to his own Delphi 2009 String Performance article. (By the way: I&#8217;m cool with people posting comments mentioning their own posts, if [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jolyon Smith</title>
		<link>http://www.deltics.co.nz/blog/?p=349&#038;cpage=1#comment-308</link>
		<dc:creator>Jolyon Smith</dc:creator>
		<pubDate>Fri, 26 Sep 2008 02:58:22 +0000</pubDate>
		<guid isPermaLink="false">http://www.deltics.co.nz/blog/?p=349#comment-308</guid>
		<description>In what way is Pos() failing?  I haven&#039;t tried this code as of course I don&#039;t have the necessary infrastructure in place.

If you can post a self-contained example I&#039;ll take a look, although CodeGear would probably be the most appropriate to look at any actual problems.</description>
		<content:encoded><![CDATA[<p>In what way is Pos() failing?  I haven&#8217;t tried this code as of course I don&#8217;t have the necessary infrastructure in place.</p>
<p>If you can post a self-contained example I&#8217;ll take a look, although CodeGear would probably be the most appropriate to look at any actual problems.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Pontus Berg</title>
		<link>http://www.deltics.co.nz/blog/?p=349&#038;cpage=1#comment-305</link>
		<dc:creator>Pontus Berg</dc:creator>
		<pubDate>Thu, 25 Sep 2008 23:18:03 +0000</pubDate>
		<guid isPermaLink="false">http://www.deltics.co.nz/blog/?p=349#comment-305</guid>
		<description>POS() fails in this key instance. Any suggestion on how to fix that is appreciated.

procedure TForm1.DBGrid1TitleClick(Column: TColumn);
{$J+}
 const PreviousColumnIndex : integer = -1;
{$J-}
begin
  if DBGrid1.DataSource.DataSet is TCustomADODataSet then
  with TCustomADODataSet(DBGrid1.DataSource.DataSet) do
  begin
    try
      DBGrid1.Columns[PreviousColumnIndex].title.Font.Style :=
      DBGrid1.Columns[PreviousColumnIndex].title.Font.Style - [fsBold];
    except
    end;

    Column.title.Font.Style := 
    Column.title.Font.Style + [fsBold];
    PreviousColumnIndex := Column.Index;

    if (Pos(Column.Field.FieldName, Sort) = 1)
    and (Pos(&#039; DESC&#039;, Sort)= 0) then
      Sort := Column.Field.FieldName + &#039; DESC&#039;
    else
      Sort := Column.Field.FieldName + &#039; ASC&#039;;
  end;
end;</description>
		<content:encoded><![CDATA[<p>POS() fails in this key instance. Any suggestion on how to fix that is appreciated.</p>
<p>procedure TForm1.DBGrid1TitleClick(Column: TColumn);<br />
{$J+}<br />
 const PreviousColumnIndex : integer = -1;<br />
{$J-}<br />
begin<br />
  if DBGrid1.DataSource.DataSet is TCustomADODataSet then<br />
  with TCustomADODataSet(DBGrid1.DataSource.DataSet) do<br />
  begin<br />
    try<br />
      DBGrid1.Columns[PreviousColumnIndex].title.Font.Style :=<br />
      DBGrid1.Columns[PreviousColumnIndex].title.Font.Style &#8211; [fsBold];<br />
    except<br />
    end;</p>
<p>    Column.title.Font.Style :=<br />
    Column.title.Font.Style + [fsBold];<br />
    PreviousColumnIndex := Column.Index;</p>
<p>    if (Pos(Column.Field.FieldName, Sort) = 1)<br />
    and (Pos(&#8217; DESC&#8217;, Sort)= 0) then<br />
      Sort := Column.Field.FieldName + &#8216; DESC&#8217;<br />
    else<br />
      Sort := Column.Field.FieldName + &#8216; ASC&#8217;;<br />
  end;<br />
end;</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jolyon Smith</title>
		<link>http://www.deltics.co.nz/blog/?p=349&#038;cpage=1#comment-291</link>
		<dc:creator>Jolyon Smith</dc:creator>
		<pubDate>Tue, 23 Sep 2008 19:33:20 +0000</pubDate>
		<guid isPermaLink="false">http://www.deltics.co.nz/blog/?p=349#comment-291</guid>
		<description>Ah yes, I should also have clarified in my &quot;Redux&quot; post that this oddity disappeared, although that was probably apparent from the results in that later exercise, which to me &quot;feel&quot; right.

There may be a couple of small surprises but there&#039;s no longer anything truly befuddling or inexplicable in there.

:)</description>
		<content:encoded><![CDATA[<p>Ah yes, I should also have clarified in my &#8220;Redux&#8221; post that this oddity disappeared, although that was probably apparent from the results in that later exercise, which to me &#8220;feel&#8221; right.</p>
<p>There may be a couple of small surprises but there&#8217;s no longer anything truly befuddling or inexplicable in there.</p>
<p> <img src='http://www.deltics.co.nz/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Anders Isaksson</title>
		<link>http://www.deltics.co.nz/blog/?p=349&#038;cpage=1#comment-288</link>
		<dc:creator>Anders Isaksson</dc:creator>
		<pubDate>Tue, 23 Sep 2008 09:51:46 +0000</pubDate>
		<guid isPermaLink="false">http://www.deltics.co.nz/blog/?p=349#comment-288</guid>
		<description>Yes, sorry my comment didn&#039;t come out clear - I was trying to explain why you can get some unintuitive result, like your

&quot;But what’s really baking my noodle now is that in Delphi 2007 the two cases give different results - TANSIString is consistently 33% faster than TString! In Delphi 7 results are identical (matching the faster of the Delphi 2007 results).&quot;

This may be just an artifact of code alignment in the library code, something which is more or less impossible to do anything about, and can drive anyone, trying to measure performance, crazy.</description>
		<content:encoded><![CDATA[<p>Yes, sorry my comment didn&#8217;t come out clear &#8211; I was trying to explain why you can get some unintuitive result, like your</p>
<p>&#8220;But what’s really baking my noodle now is that in Delphi 2007 the two cases give different results &#8211; TANSIString is consistently 33% faster than TString! In Delphi 7 results are identical (matching the faster of the Delphi 2007 results).&#8221;</p>
<p>This may be just an artifact of code alignment in the library code, something which is more or less impossible to do anything about, and can drive anyone, trying to measure performance, crazy.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jolyon Smith</title>
		<link>http://www.deltics.co.nz/blog/?p=349&#038;cpage=1#comment-287</link>
		<dc:creator>Jolyon Smith</dc:creator>
		<pubDate>Tue, 23 Sep 2008 08:34:33 +0000</pubDate>
		<guid isPermaLink="false">http://www.deltics.co.nz/blog/?p=349#comment-287</guid>
		<description>Hi Anders,

Thanks for the detailed and insightful comments.

No, I didn&#039;t follow those discussions you refer to, but I am aware of the difficulty with metrics.

I think the playing field was levelled as far as possible (following the &quot;Redux&quot; testing at least) given that I did not set out to establish the fastest possible code producable from each compiler but rather given the same set of typical conditions (bog standard project settings etc) how did the results from each compare.</description>
		<content:encoded><![CDATA[<p>Hi Anders,</p>
<p>Thanks for the detailed and insightful comments.</p>
<p>No, I didn&#8217;t follow those discussions you refer to, but I am aware of the difficulty with metrics.</p>
<p>I think the playing field was levelled as far as possible (following the &#8220;Redux&#8221; testing at least) given that I did not set out to establish the fastest possible code producable from each compiler but rather given the same set of typical conditions (bog standard project settings etc) how did the results from each compare.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Anders Isaksson</title>
		<link>http://www.deltics.co.nz/blog/?p=349&#038;cpage=1#comment-286</link>
		<dc:creator>Anders Isaksson</dc:creator>
		<pubDate>Tue, 23 Sep 2008 08:12:26 +0000</pubDate>
		<guid isPermaLink="false">http://www.deltics.co.nz/blog/?p=349#comment-286</guid>
		<description>Jolyon, if you followed the FastCode discussions in .basm, you might remember all the work that had to be done to get the benchmarks reliable, with statistical significance. It&#039;s no easy feat to actually know what has been tested/measured...

One thing I haven&#039;t seen mentioned here is code alignment. From the FastCode experience, we know that code alignment can be the decisive factor for best performance - and we have no control over that!

Experimenting with the code, adding nop instructions here and there to align the inner loops can give a large boost, which immediately is lost as soon as *any* code is changed *anywhere* else in the project...

Then there&#039;s also stack alignment of local variables, which also can give measurable differences for anything larger than two bytes. This can partly be controlled, by adding dummy declarations, but there isn&#039;t any real control over this either.

AndersI</description>
		<content:encoded><![CDATA[<p>Jolyon, if you followed the FastCode discussions in .basm, you might remember all the work that had to be done to get the benchmarks reliable, with statistical significance. It&#8217;s no easy feat to actually know what has been tested/measured&#8230;</p>
<p>One thing I haven&#8217;t seen mentioned here is code alignment. From the FastCode experience, we know that code alignment can be the decisive factor for best performance &#8211; and we have no control over that!</p>
<p>Experimenting with the code, adding nop instructions here and there to align the inner loops can give a large boost, which immediately is lost as soon as *any* code is changed *anywhere* else in the project&#8230;</p>
<p>Then there&#8217;s also stack alignment of local variables, which also can give measurable differences for anything larger than two bytes. This can partly be controlled, by adding dummy declarations, but there isn&#8217;t any real control over this either.</p>
<p>AndersI</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Te Waka o Delphi &#183; Delphi 2009 - StringPerformance Redux</title>
		<link>http://www.deltics.co.nz/blog/?p=349&#038;cpage=1#comment-268</link>
		<dc:creator>Te Waka o Delphi &#183; Delphi 2009 - StringPerformance Redux</dc:creator>
		<pubDate>Mon, 22 Sep 2008 08:38:31 +0000</pubDate>
		<guid isPermaLink="false">http://www.deltics.co.nz/blog/?p=349#comment-268</guid>
		<description>[...] conclusions from the previous exercise to benchmark string performance in Delphi 2009.</description>
		<content:encoded><![CDATA[<p>[...] conclusions from the previous exercise to benchmark string performance in Delphi 2009.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Bruce McGee</title>
		<link>http://www.deltics.co.nz/blog/?p=349&#038;cpage=1#comment-265</link>
		<dc:creator>Bruce McGee</dc:creator>
		<pubDate>Fri, 19 Sep 2008 22:09:30 +0000</pubDate>
		<guid isPermaLink="false">http://www.deltics.co.nz/blog/?p=349#comment-265</guid>
		<description>Just nit-picking a little.  

As for the results file, I was also thinking of people who don&#039;t use Microsoft Office at all.</description>
		<content:encoded><![CDATA[<p>Just nit-picking a little.  </p>
<p>As for the results file, I was also thinking of people who don&#8217;t use Microsoft Office at all.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jolyon Smith</title>
		<link>http://www.deltics.co.nz/blog/?p=349&#038;cpage=1#comment-264</link>
		<dc:creator>Jolyon Smith</dc:creator>
		<pubDate>Fri, 19 Sep 2008 20:17:19 +0000</pubDate>
		<guid isPermaLink="false">http://www.deltics.co.nz/blog/?p=349#comment-264</guid>
		<description>@Kryvich - no worries about posting the dumps - please don&#039;t think that I don&#039;t appreciate it, it was just that once I was able to &quot;certify&quot; that they were identical the actual dumps themselves were surplus to requirement and bit &quot;noisy&quot;, that&#039;s all.  But it was absolutely useful to have them posted in the first place, so all good.

:)

My feeling is that external factors should lead to variations and inconsistencies in results - i.e. in this case sometimes String might be faster than ANSIString and vice versa, or the difference may vary, but this strange discrepancy in Delphi 2007 is consistently repeatable even if I reverse the order of the tests (run ANSIString cases before String), for example.

As far as multithreading influences might go - SmokeTest runs it&#039;s test cases on a worker thread, separate from the main thread.  I am running the tests on a dual core system, but SmokeTest is implemented to detect this and in an N-core situation it sets the affinity of the main thread to CPU 1 and the worker thread to CPU 2.

It&#039;s not perfect but it should, in theory at least, remove context switching artefacts from the results if nothing else.

CPU Cache is a good point and I have a &quot;note to self&quot; to investigate adding calls to flush the CPU cache (something I discovered when researching my VMT patching hack) for performance test cases.

I shall re-run the tests with these changes in place and post the results.


@Bruce - I probably should but I&#039;m not sure that SmokeTest itself will even compile on Delphi.NET and the compiler versions are accurate enough for Win32.  :)

I did think of saving in an older Excel format but the gradient colour scheme used in the results wasn&#039;t portable, according to the file-save-as warning that I got anyway.

But as well as the Excel viewer, there is also the Office Compatibility pack that, aiui, will allow older Office applications to open 2007 files:

http://www.microsoft.com/downloads/details.aspx?FamilyID=941b3470-3ae9-4aee-8f43-c6bb74cd1466&amp;displaylang=en</description>
		<content:encoded><![CDATA[<p>@Kryvich &#8211; no worries about posting the dumps &#8211; please don&#8217;t think that I don&#8217;t appreciate it, it was just that once I was able to &#8220;certify&#8221; that they were identical the actual dumps themselves were surplus to requirement and bit &#8220;noisy&#8221;, that&#8217;s all.  But it was absolutely useful to have them posted in the first place, so all good.</p>
<p> <img src='http://www.deltics.co.nz/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>My feeling is that external factors should lead to variations and inconsistencies in results &#8211; i.e. in this case sometimes String might be faster than ANSIString and vice versa, or the difference may vary, but this strange discrepancy in Delphi 2007 is consistently repeatable even if I reverse the order of the tests (run ANSIString cases before String), for example.</p>
<p>As far as multithreading influences might go &#8211; SmokeTest runs it&#8217;s test cases on a worker thread, separate from the main thread.  I am running the tests on a dual core system, but SmokeTest is implemented to detect this and in an N-core situation it sets the affinity of the main thread to CPU 1 and the worker thread to CPU 2.</p>
<p>It&#8217;s not perfect but it should, in theory at least, remove context switching artefacts from the results if nothing else.</p>
<p>CPU Cache is a good point and I have a &#8220;note to self&#8221; to investigate adding calls to flush the CPU cache (something I discovered when researching my VMT patching hack) for performance test cases.</p>
<p>I shall re-run the tests with these changes in place and post the results.</p>
<p>@Bruce &#8211; I probably should but I&#8217;m not sure that SmokeTest itself will even compile on Delphi.NET and the compiler versions are accurate enough for Win32.  <img src='http://www.deltics.co.nz/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>I did think of saving in an older Excel format but the gradient colour scheme used in the results wasn&#8217;t portable, according to the file-save-as warning that I got anyway.</p>
<p>But as well as the Excel viewer, there is also the Office Compatibility pack that, aiui, will allow older Office applications to open 2007 files:</p>
<p><a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=941b3470-3ae9-4aee-8f43-c6bb74cd1466&#038;displaylang=en" rel="nofollow">http://www.microsoft.com/downloads/details.aspx?FamilyID=941b3470-3ae9-4aee-8f43-c6bb74cd1466&#038;displaylang=en</a></p>
]]></content:encoded>
	</item>
</channel>
</rss>
