<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>More on Perf\Productivity: The devil is in the details...</title><link>http://blogs.msdn.com/b/brada/archive/2004/06/13/154866.aspx</link><description>I enjoyed reading (and forwarding) the comments on my recent post on the productivity performance tradeoff&amp;#8230; Many of you (rightly so) pointed out that the details really mater in such a discussion. So I picked one that we are struggling with right</description><dc:language>en-US</dc:language><generator>Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><item><title>The &amp;amp;quot;Halloween Problem&amp;amp;quot; for XML APIs</title><link>http://blogs.msdn.com/b/brada/archive/2004/06/13/154866.aspx#672212</link><pubDate>Thu, 20 Jul 2006 07:05:07 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:672212</guid><dc:creator>mikechampion's weblog</dc:creator><description>Don't feel bad if you don't know what the Halloween problem is.&amp;amp;amp;nbsp; According to the Transact SQL Blog,...&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=672212" width="1" height="1"&gt;</description></item><item><title>re: More on Perf\Productivity: The devil is in the details...</title><link>http://blogs.msdn.com/b/brada/archive/2004/06/13/154866.aspx#158342</link><pubDate>Thu, 17 Jun 2004 16:55:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:158342</guid><dc:creator>Mark Levison</dc:creator><description>Keep the check in.  If we've got performance problems that need work, they are likely far bigger than this little check.&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=158342" width="1" height="1"&gt;</description></item><item><title>re: More on Perf\Productivity: The devil is in the details...</title><link>http://blogs.msdn.com/b/brada/archive/2004/06/13/154866.aspx#157966</link><pubDate>Thu, 17 Jun 2004 08:58:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:157966</guid><dc:creator>Cyrus Najmabadi</dc:creator><description>I agree with Poust: &lt;br&gt;&lt;br&gt;Unless you can formalize what it means to change an underlying collection while iterating over it, then you should probably throw as an unsupported operation.&lt;br&gt;&lt;br&gt;For example, if I am iterating over a tree then I expect to get every element in the tree.  If someone removes an element which causes a rebalance then it's almost certainly gauranteed that the iterator will be in a hosed position at that point and that continuing the iteration will not give me all the correc telements (it might return an old element again, or it may miss elements).  Because of this it's better to throw and make the consumer realize that they are almost definitely not doing the right thing.&lt;br&gt;&lt;br&gt;If you need to expose mutability semantics that work in the presense of iteration, then it needs to be something that works hand-in-hand with the iterator.  For that reason I see those operations as being better suited on the iterator.  If you want to add an element, tell the iterator.  This will ensure that after the operation the iterator and underlying collection will be in a sane state.&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=157966" width="1" height="1"&gt;</description></item><item><title>re: More on Perf\Productivity: The devil is in the details...</title><link>http://blogs.msdn.com/b/brada/archive/2004/06/13/154866.aspx#156988</link><pubDate>Wed, 16 Jun 2004 11:25:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:156988</guid><dc:creator>W Poust</dc:creator><description>Let's see... if we extend the performance argument, I should take out all the error checking in my code and all will be good and lightning fast as well.  Sounds good to me; no more writing those pesky if statements.&lt;br&gt;&lt;br&gt;I just don't buy it.  For our customers, stability and security go hand-in-glove.  Without the error checking, you miss the obvious logic error (which is based on implementation details).  Would the error be found in testing? Maybe - depends on the tests performed.  Would the error be found in the field? Definitely.  That's not a good place or time for discovering nuances about the underying library.&lt;br&gt;&lt;br&gt;If statements comparing values in memory for error checking are essentually free.  Thank the hard working engineers at Intel for their instruction pipeline optimizations.  Please sprinkle on liberally.&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=156988" width="1" height="1"&gt;</description></item><item><title>re: More on Perf\Productivity: The devil is in the details...</title><link>http://blogs.msdn.com/b/brada/archive/2004/06/13/154866.aspx#155474</link><pubDate>Mon, 14 Jun 2004 22:09:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:155474</guid><dc:creator>Frank Hileman</dc:creator><description>Correction: in the enumerator, don't check to see if Count changed -- just check to see if the enumerator is going out of bounds, by using Count.&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=155474" width="1" height="1"&gt;</description></item><item><title>re: More on Perf\Productivity: The devil is in the details...</title><link>http://blogs.msdn.com/b/brada/archive/2004/06/13/154866.aspx#155473</link><pubDate>Mon, 14 Jun 2004 22:06:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:155473</guid><dc:creator>Frank Hileman</dc:creator><description>I agree essentially with Justin. We created some base collection classes in VG.net and had to make the exact same decision. We decided to remove the version number, not because it makes the loop slower, but because it makes every instance of the collection larger. This is a more important factor. That version number is not retaining useful information most of the time, and is wasteful. Why force everyone to store it?&lt;br&gt;&lt;br&gt;As Justin points out, you can eliminate any possible exceptions by making the enumerator more robust, checking to see if the Count changed. This does not prevent changes to the list, but actually adds flexibility -- limited changes might be allowed. If people really want to change the list and iterate at the same time, they can always use a copy, or for (int i = 0; i &amp;lt;....).&lt;br&gt;&lt;br&gt;So put error checking in the enumerator, and let users use the &amp;quot;for&amp;quot; to get max speed.&lt;br&gt;&lt;br&gt;This argument applies to an ArrayList type of class, not a true linked list.&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=155473" width="1" height="1"&gt;</description></item><item><title>re: More on Perf\Productivity: The devil is in the details...</title><link>http://blogs.msdn.com/b/brada/archive/2004/06/13/154866.aspx#155299</link><pubDate>Mon, 14 Jun 2004 18:17:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:155299</guid><dc:creator>Philip Rieck</dc:creator><description>While I thank you for a specific case, I think this question is moot.&lt;br&gt;&lt;br&gt;We already have the choice (as pointed out above) :&lt;br&gt;1. Use foreach(...).  I'm relying on a shortcut to produce easy code without having to take control of all the details.   &lt;br&gt;&lt;br&gt;2. Use for(...).  I'm taking control of the details, and I know enough about how the class (List&amp;lt;t&amp;gt; in this case) works to enumerate it myself.  I'm doing that because I understand the issues, and need the benefits that all this extra work will get me.&lt;br&gt;&lt;br&gt;&lt;br&gt;It seems to me that developers in case one are clearly saying &amp;quot;productivity for me, please&amp;quot;, and are willing to take a small perf hit.   In case #2 the developer is saying &amp;quot;I know the risks, give me control&amp;quot;, and can address thier own perf issues.&lt;br&gt;&lt;br&gt;I'd be more interested in an example you have where we *can't* have it both ways.  I think the discussion may be a bit more heated.    Personally, when choosing between perf and productivity, I want both.. :)&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=155299" width="1" height="1"&gt;</description></item><item><title>re: More on Perf\Productivity: The devil is in the details...</title><link>http://blogs.msdn.com/b/brada/archive/2004/06/13/154866.aspx#155215</link><pubDate>Mon, 14 Jun 2004 16:24:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:155215</guid><dc:creator>Keith Hill</dc:creator><description>Keep the check for productivity, use the for loop for performance if necessary. Also to get around the bugs with removing elements as you walk a collection, just walk it in the reverse direction.&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=155215" width="1" height="1"&gt;</description></item><item><title>re: More on Perf\Productivity: The devil is in the details...</title><link>http://blogs.msdn.com/b/brada/archive/2004/06/13/154866.aspx#155140</link><pubDate>Mon, 14 Jun 2004 14:43:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:155140</guid><dc:creator>Justin Rogers</dc:creator><description>To explain why you get the NullRef instead of the IndexOutOfRangeException, you have to understand there is a larger underlying array in this example.  Say it is 20 elements.  As the enumerator goes through the list, it just increments an offset.  Once you get to element 7, and one of your elements is already gone, it will return whatever is in the underlying array, which in this case is null.  This is a very insidious issue because the enumerator uses a fixed end-index instead of a count.&lt;br&gt;&lt;br&gt;Now, you might ask, why does it happen on element 7?  Well, we started with 7 elements and so endindex is giong to be 7 (6 actually).  Then we removed element KCwalina, and the entire array underneath gets shifted down by 1.  That puts Kit at the current offset, meaning we skip this element entirely.  The next MoveNext will increment us one and put us on Peter.&lt;br&gt;&lt;br&gt;Brad actually got to demonstrate two bugs with a single sample.  One bug is the array element skipping  If I were using a for loop and I removed an element based on index, I would decement my index pointer, so the next time through the loop, I was placed at the same index and could process the new element.  You might try to be savvy and just bump to the top of the for...loop, but this offers up the problem of whether or not this was already the last element in the list so there wouldn't be any more elements to process (a third type of issue).&lt;br&gt;&lt;br&gt;The second bug is walking past the end of the list, but still living within the bounds of the underlying array, in which case you'll get null's for object types, and even worse, 0's for integer types, and 0.0 for float types.  You can see where that would really suck, because you wouldn't even know what you had done, since you won't get a NullRef and you won't get any bounding exceptions either.&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=155140" width="1" height="1"&gt;</description></item><item><title>re: More on Perf\Productivity: The devil is in the details...</title><link>http://blogs.msdn.com/b/brada/archive/2004/06/13/154866.aspx#155015</link><pubDate>Mon, 14 Jun 2004 10:20:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:155015</guid><dc:creator>David Levine</dc:creator><description>For most situations leaving the check in would provide the most benefit, especially since the 1st test run that exercised the .Remove call would throw an exception, providing instant feedback during a test of a bug. Taking out the check means that testing may not even find this if the test data does not include all the edge cases.&lt;br&gt;&lt;br&gt;Since taking out the check results in a misleading NullReferenceException this is even more reason to leave it in. When the foreach accesses the list with a bad index (beyond its end) I would have expected an IndexOutOfRangeException. Instead, it must be casting the result to a null string reference. How is the Current property implemented? Misleading information is almost as bad as no information.&lt;br&gt;&lt;br&gt;I agree with Justin - if I want high performance I'll use a for loop where I explicitly take on the responsibility of handling the list correctly. &lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=155015" width="1" height="1"&gt;</description></item></channel></rss>