<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0"><channel><title>Guy Ellis Rocks</title><link>http://guyellisrocks.com/</link><description>C# ASP.NET SQL SERVER</description><generator>Graffiti CMS 1.1 (build 1.1.0.1114)</generator><lastBuildDate>Mon, 09 Nov 2009 20:40:00 GMT</lastBuildDate><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/guyellisrocks" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item><title>Speed improvements with compiled regex</title><link>http://guyellisrocks.com/coding/speed-improvements-with-compiled-regex/</link><pubDate>Mon, 09 Nov 2009 20:40:00 GMT</pubDate><guid isPermaLink="true">http://guyellisrocks.com/coding/speed-improvements-with-compiled-regex/</guid><dc:creator>guy ellis</dc:creator><slash:comments>0</slash:comments><category domain="http://guyellisrocks.com/coding/">coding</category><description>&lt;p&gt;During a code review I was told that a compiled regex would work faster. I had no doubt that this was true but I wanted to know how much faster and at what cost. I setup and ran the following test.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;static void TestCompiledRegex()&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; string regexString = @&amp;quot;(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})&amp;quot;;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Regex compiledRegex = new Regex(regexString, RegexOptions.Compiled);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Regex uncompiledRegex = new Regex(regexString, RegexOptions.None);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; double totalFaster = 0d;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; int numIterations = 0;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int j = 10; j &amp;lt;= 100; j += 10)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TimeSpan uncompiledTime = RunRegex(uncompiledRegex, j);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TimeSpan compiledTime = RunRegex(compiledRegex, j);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; double timesFaster = uncompiledTime.TotalMilliseconds / compiledTime.TotalMilliseconds;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(&amp;quot;For {0} GUIDS compiled takes {1} and non-compiled takes {2}. Compiled is {3:0.00} faster&amp;quot;, j, compiledTime, uncompiledTime, timesFaster);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; totalFaster += timesFaster;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; numIterations++;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(&amp;quot;Average times faster: {0:0.00}&amp;quot;, totalFaster/(double)numIterations);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.ReadLine();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
static TimeSpan RunRegex(Regex regex, int numGuids)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; int x;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; string input = GetStringWithGuids(numGuids);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; DateTime startTime = DateTime.Now;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i = 0; i &amp;lt; 10000; i++)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MatchCollection mc = regex.Matches(input);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; x = mc.Count;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return DateTime.Now - startTime;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
static string GetStringWithGuids(int numGuids)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; StringBuilder sb = new StringBuilder();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i = 0; i &amp;lt; numGuids; i++)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(Guid.NewGuid().ToString() + &amp;quot; spacer &amp;quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return sb.ToString();&lt;br /&gt;
}&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The result was that the compiled regex ran 1.6 times faster than the uncompiled version.&lt;/p&gt;
&lt;p&gt;I then split the RunRegex function into two functions and moved the creation of the Regex object into these functions making one of them compiled and the other not.&lt;/p&gt;
&lt;p&gt;On text with 10 GUIDs in it the uncompiled version ran 42 times faster than the compiled version. The number of times faster diminished as the number of GUID's (matches) in the string increased until the uncompiled version was six times faster when we had 100 matches in the string.&lt;/p&gt;
&lt;p&gt;The next test was to decrease the number of matches to non-matches in the text so I adjusted the GetStringWithGuids() function to add 100 &amp;quot;spacers&amp;quot; between each GUID. Remember that the listed GetStringWithGuids() above has 1 match (GUID) per non-match(&amp;quot; spacer &amp;quot;). The new function looked like this:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;static string GetStringWithGuids(int numGuids)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; StringBuilder sb = new StringBuilder();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; string spacer = String.Join(&amp;quot; &amp;quot;, Enumerable.Repeat(&amp;quot;spacer&amp;quot;, 100).ToArray());&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i = 0; i &amp;lt; numGuids; i++)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(Guid.NewGuid().ToString() + &amp;quot; &amp;quot; + spacer + &amp;quot; &amp;quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return sb.ToString();&lt;br /&gt;
}&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;For 10 GUIDs the uncompiled version performed 2.7 times better but at 50 GUIDs the compiled version started performing better through to 100 GUIDs.&lt;/p&gt;
&lt;p&gt;So the only test left was the one that was truly representative of the data that I was going to run this against which was a block of text with a single GUID in it.&lt;/p&gt;
&lt;p&gt;The new GetStringWithGuids() function with redundant parameter looked like this:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;static string GetStringWithGuids(int numGuids)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; StringBuilder sb = new StringBuilder();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; string spacer = String.Join(&amp;quot; &amp;quot;, Enumerable.Repeat(&amp;quot;spacer&amp;quot;, 100).ToArray());&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(spacer + &amp;quot; &amp;quot; + Guid.NewGuid().ToString() + &amp;quot; &amp;quot; + spacer);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return sb.ToString();&lt;br /&gt;
}&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This showed the uncompiled version to be 10 times faster than the compiled version.&lt;/p&gt;</description></item><item><title>Is this string numeric in C# part 3</title><link>http://guyellisrocks.com/coding/is-this-string-numeric-in-c-part-3/</link><pubDate>Sun, 08 Nov 2009 18:49:00 GMT</pubDate><guid isPermaLink="true">http://guyellisrocks.com/coding/is-this-string-numeric-in-c-part-3/</guid><dc:creator>guy ellis</dc:creator><slash:comments>0</slash:comments><category domain="http://guyellisrocks.com/coding/">coding</category><description>&lt;p&gt;Following on from &lt;a href="http://guyellisrocks.com/coding/is-this-string-numeric-in-c-part-2/"&gt;Is this string numeric in C# part 2&lt;/a&gt;...&lt;/p&gt;
&lt;p&gt;Curiosity got the better of me and I wanted to know what the IsDigit and TryParse functions did. There's a &lt;a href="http://blogs.msdn.com/sburke/archive/2008/01/16/configuring-visual-studio-to-debug-net-framework-source-code.aspx"&gt;post here &lt;/a&gt;by Shawn Burke that details how to setup Visual Studio to allow you to step into the .NET source. From that I found the IsDigit() source to be exactly what we'd surmised:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;public static bool IsDigit(char c) {&lt;br /&gt;
&amp;nbsp; if (IsLatin1(c)) { &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return (c &amp;gt;= '0' &amp;amp;&amp;amp; c &amp;lt;= '9'); &lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&amp;nbsp; return (CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.DecimalDigitNumber); &lt;br /&gt;
}&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In both scenarios you'd expect Jon's function to perform better and even more so in the numeric string. When checking the numeric string every single character needs to be checked so the additional overhead for the IsLatin1() call should slow down Guy's function more. However, the results show Guy's function performing better when the string is numeric.&lt;/p&gt;
&lt;p&gt;When the string is non numeric from the first character then you'd expect Jon's function to perform better but only just.&lt;/p&gt;
&lt;p&gt;I can't explain why Guy's function is currently out-performing Jon's at the moment. There must be a flaw in my testing setup.&lt;/p&gt;
&lt;p&gt;I was, however, completely wrong about the TryParse function. It does not throw an exception but it is a much larger and more nested function than I was expecting and executes dozens of code paths and this is what's slowing this down. Also, if you think about it the TryParse is converting from one type to another so the complete conversion is taking place while in our IsDigit function we are just checking to see if it's possible to convert the string to a number and not actually doing the conversion. So in addition to doing the check on each character, the TryParse is also writing those characters to a memory space to create a numeric value. That's where the performance hit comes in.&lt;/p&gt;
&lt;p&gt;Jon also suggested modifying his function to assigning the char to a local variable before using it as the index operator makes a function call so I tried by modifying his function to:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Func&amp;lt;string, bool&amp;gt; isNumeric_Jon =&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; delegate(string s)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i = 0; i &amp;lt; s.Length; i++)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; char c = s[i];&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (c &amp;gt; '9' || c &amp;lt; '0')&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return false;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return true;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;However, this made no difference in the tests. My guess is that the compiler had already optimized the two identical references into one.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description></item><item><title>Up or down for version number on C# 4.0?</title><link>http://guyellisrocks.com/coding/up-or-down-for-version-number-on-c-4-0/</link><pubDate>Sat, 07 Nov 2009 07:06:00 GMT</pubDate><guid isPermaLink="true">http://guyellisrocks.com/coding/up-or-down-for-version-number-on-c-4-0/</guid><dc:creator>guy ellis</dc:creator><slash:comments>0</slash:comments><category domain="http://guyellisrocks.com/coding/">coding</category><description>&lt;p&gt;Not sure if you were up-to-speed on the compiler version numbering that's been used with C# but just in case you weren't this is what version number the compiler calls itself when run from the \windows\microsoft.net\framework\ folders...&lt;/p&gt;
&lt;p&gt;(click image to see full size)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://guyellisrocks.com/files/uploads/csc_versions.png"&gt;&lt;img alt="Task Manager" src="http://guyellisrocks.com/files/uploads/csc_versions.png" style="border: 5px solid rgb(136, 136, 136); margin: 10px; padding: 10px; width: 450px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We went from version 7 to 8 and then to 3.5...&lt;/p&gt;
&lt;p&gt;That's not the most logical progression of numbers that I've ever seen. I haven't installed the C# 4.0 beta compiler yet so I don't know what the version number will be. My thinking is that if I ever went for a job interview with Microsoft I am definitely going to find out what it is because on that job IQ test they'll have a number progression question and it will be what comes after 7, 8, 3.5 __ and I will then know the answer.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description></item><item><title>Standing on the shoulders of giants</title><link>http://guyellisrocks.com/random/standing-on-the-shoulders-of-giants/</link><pubDate>Sat, 07 Nov 2009 06:54:08 GMT</pubDate><guid isPermaLink="true">http://guyellisrocks.com/random/standing-on-the-shoulders-of-giants/</guid><dc:creator>guy ellis</dc:creator><slash:comments>0</slash:comments><category domain="http://guyellisrocks.com/random/">random</category><description>&lt;p&gt;As arrogant as my domain name is &amp;quot;Guy Ellis Rocks Dot Com&amp;quot;, I only chose it because Standing On The Shoulders Of Giants Dot Com was already taken. I've always attributed this quote to Sir Isaac Newton but &lt;a href="http://en.wikipedia.org/wiki/Standing_on_the_shoulders_of_giants"&gt;just learned&lt;/a&gt; that it was originally coined by Bernard of Chartres.&lt;/p&gt;
&lt;p&gt;I take a moment to be humble and acknowledge that almost everything that you see on this blog is the synthesis of giants who have helped me and who's work I have read.&lt;/p&gt;</description></item><item><title>Is this string numeric in C# part 2</title><link>http://guyellisrocks.com/coding/is-this-string-numeric-in-c-part-2/</link><pubDate>Sat, 07 Nov 2009 06:35:00 GMT</pubDate><guid isPermaLink="true">http://guyellisrocks.com/coding/is-this-string-numeric-in-c-part-2/</guid><dc:creator>guy ellis</dc:creator><slash:comments>1</slash:comments><category domain="http://guyellisrocks.com/coding/">coding</category><description>&lt;p&gt;I heard back from &lt;a href="http://bbrown.info/"&gt;Bill&lt;/a&gt; and &lt;a href="http://hohle.net/"&gt;Jon&lt;/a&gt; with some suggestions about improving the algorithm for speed in the IsNumeric(string) function documented at &lt;a href="http://guyellisrocks.com/coding/is-this-string-numeric-in-c/"&gt;Is this string numeric in C#?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Bill's idea was to use the return value from &lt;strong&gt;Int64.TryParse()&lt;/strong&gt; and Jon's idea was to compare the values of each character to their digital character equivalents and check the greater or less than in the ascii sequence using &lt;strong&gt;if (s[i] &amp;gt; '9' || s[i] &amp;lt; '0')&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;My initial gut-feel reaction was that Jon's would be faster and Bill's slower. The reason that I thought that Jon's would be faster is because I am under the impression that IsDigit() checks other digits outside of the 0 to 9 range to take into account other digit sets such as Thai. Bill's I thought would be slower because I think that TryParse() catches a thrown exception when returning false and so the expense of exception handling would cause it to be slow.&lt;/p&gt;
&lt;p&gt;The first problem that I hit was that the original numeric string that I used:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;string numericString = &amp;quot;12345678901234567890123456&amp;quot;;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;was too large for Int64. I didn't pick this up at first and when I ran the first set of tests they completed turned my expectations on their head with Bill's being fastest and then mine and then Jon's. However, these results were invalid as the Int64.TryParse() call was not returning the correct results.&lt;/p&gt;
&lt;p&gt;I fixed the test code to look like this and re-ran it all.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;static string numericString = &amp;quot;1234567890123456&amp;quot;;&lt;br /&gt;
static string nonNumericString = &amp;quot;abcdefghijklmnopqrstuvwxyz&amp;quot;;&lt;br /&gt;
static void DigitTesting()&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Func&amp;lt;string, bool&amp;gt; isNumeric_Guy =&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; delegate(string s)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i = 0; i &amp;lt; s.Length; i++)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!Char.IsDigit(s[i]))&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return false;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return true;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Func&amp;lt;string, bool&amp;gt; isNumeric_Jon =&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; delegate(string s)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i = 0; i &amp;lt; s.Length; i++)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (s[i] &amp;gt; '9' || s[i] &amp;lt; '0')&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return false;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return true;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Func&amp;lt;string, bool&amp;gt; isNumeric_Bill =&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; delegate(string s)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Int64 number;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (Int64.TryParse(s, out number))&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return true;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return false;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Func&amp;lt;string, bool&amp;gt;[] functions = {isNumeric_Guy, isNumeric_Jon, isNumeric_Bill };&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (Func&amp;lt;string, bool&amp;gt; function in functions)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DateTime startTime = DateTime.Now;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i = 0; i &amp;lt; 100000000; i++)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; function(numericString);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(&amp;quot;numberic: {0} time taken: {1}&amp;quot;,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; function.Method.Name, DateTime.Now - startTime);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.ReadLine();&lt;br /&gt;
}&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Against a numeric string IsNumeric_Guy() turned out to be about 15% faster than IsNumeric_Jon() and about 31% faster than IsNumeric_Bill().&lt;/p&gt;
&lt;p&gt;When testing against a non-numeric string IsNumeric_Jon() showed up 16% faster than IsNumeric_Guy() and 87% faster than IsNumeric_Bill(). This is how I would have expected the results to be in both cases.&lt;/p&gt;
&lt;p&gt;This is an interesting conundrum to end up at with two algorithms both beating each other by the same amount under different data types. Luckily I know that most of the data that this algorithm will be looking at will be non-numeric strings and so I will go with Jon's algorithm.&lt;/p&gt;
&lt;p&gt;Thanks &lt;a href="http://bbrown.info/"&gt;Bill&lt;/a&gt; and &lt;a href="http://hohle.net/"&gt;Jon&lt;/a&gt;  - your ideas and help are much appreciated.&lt;/p&gt;
&lt;p&gt;Continued in &lt;a href="http://guyellisrocks.com/coding/is-this-string-numeric-in-c-part-3/"&gt;Is this string numeric in C# part 3&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Is this string numeric in C#?</title><link>http://guyellisrocks.com/coding/is-this-string-numeric-in-c/</link><pubDate>Fri, 06 Nov 2009 23:52:00 GMT</pubDate><guid isPermaLink="true">http://guyellisrocks.com/coding/is-this-string-numeric-in-c/</guid><dc:creator>guy ellis</dc:creator><slash:comments>3</slash:comments><category domain="http://guyellisrocks.com/coding/">coding</category><description>&lt;p&gt;On a completely unrelated project to my previous post about &lt;a href="http://guyellisrocks.com/coding/optimizing-a-custom-trim-function-in-c/"&gt;Optimizing a custom Trim() function in C#&lt;/a&gt; where I was stripping non-numeric characters from either end of a string that may have digits in it I found myself battling with a slow running console application that needed profiling.&lt;/p&gt;
&lt;p&gt;Someone had recommended &lt;a href="http://www.eqatec.com/tools/profiler"&gt;EQATEC Profiler&lt;/a&gt; to me and so I ran it against this console app to find where the slowness was coming from. It turned out that the bottleneck was in an IsNumeric function:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;private readonly static Regex NumericRegex = &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; new Regex(@&amp;quot;^[0-9]+$&amp;quot;, RegexOptions.Compiled);&lt;br /&gt;
bool IsNumeric(string Text)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return NumericRegex.IsMatch(Text);&lt;br /&gt;
}&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When I discovered how frequently this was being called I went about optimizing it and came up with:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;bool IsNumeric(string s)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i = 0; i &amp;lt; s.Length; i++)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!Char.IsDigit(s[i]))&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return false;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return true;&lt;br /&gt;
}&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I then tested the two functions on two different strings:&lt;/p&gt;
&lt;p&gt;string numericString = &amp;quot;12345678901234567890123456&amp;quot;;&lt;br /&gt;
string nonNumericString = &amp;quot;abcdefghijklmnopqrstuvwxyz&amp;quot;;&lt;/p&gt;
&lt;p&gt;To see how they would fare against each other. On the numeric string the new function ran 3 times faster than the old regex one. On the non-numeric string it was a factor of nine. The reason for the huge difference in performance gain between the two types of strings should be fairly obvious. For the non-numeric string the new function bails out of the call immediately after inspection of the first character while the regex would still examine the whole string. For the numeric string both functions would need to examine every single character before returning.&lt;/p&gt;
&lt;p&gt;More tests with 2 new algorithms from comment and email: &lt;a href="http://guyellisrocks.com/coding/is-this-string-numeric-in-c-part-2/"&gt;Part 2&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Delegates and Lambdas in C#</title><link>http://guyellisrocks.com/coding/delegates-and-lambdas-in-c/</link><pubDate>Fri, 06 Nov 2009 21:46:36 GMT</pubDate><guid isPermaLink="true">http://guyellisrocks.com/coding/delegates-and-lambdas-in-c/</guid><dc:creator>guy ellis</dc:creator><slash:comments>0</slash:comments><category domain="http://guyellisrocks.com/coding/">coding</category><description>&lt;p&gt;I was just explaining delegates and lambdas to a friend and thought that I'd write up an example for him.&lt;/p&gt;
&lt;p&gt;Here is an IEnumerable&amp;lt;&amp;gt; that we want to interrogate to get all values greater than or equal to 60:&lt;br /&gt;
&lt;strong&gt;int[] scores = { 45, 55, 59, 65, 66, 67, 68 };&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Here is how we could do it using a delegate. We declare a Func&amp;lt;T, TResult&amp;gt; type which is the same as a pointer to a function in C. In our following LINQ statement we pass that function pointer (delegate) as the &amp;quot;predicate&amp;quot; in the Where &amp;quot;clause.&amp;quot; The Where() extension method will be passing in each int one at a time and expect a bool true/false result back. That's why we declared the delegate as a Func&amp;lt;int, bool&amp;gt;, the int is what we're passing in and the bool is the return type.&lt;br /&gt;
&lt;strong&gt;Func&amp;lt;int, bool&amp;gt; predicate = delegate(int score) { return score &amp;gt;= 60; };&lt;br /&gt;
IEnumerable&amp;lt;int&amp;gt; passingScores1 = scores.Where(predicate);&lt;br /&gt;
&lt;/strong&gt;&lt;br /&gt;
LINQ makes the above syntax much easier for us. In the parameter to the Where() extension method we can declare the body of the function so long as it adheres to the prototype of int parameter and bool return.&lt;br /&gt;
&lt;strong&gt;IEnumerable&amp;lt;int&amp;gt; passingScores2 = scores.Where((int score) =&amp;gt; score &amp;gt;= 60);&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
The compiler can infer the type that's being passed in as the parameter so we can drop the &lt;strong&gt;(int score)&lt;/strong&gt; and replace it with &lt;strong&gt;score&lt;/strong&gt; if you want even more brevity.&lt;br /&gt;
&lt;strong&gt;IEnumerable&amp;lt;int&amp;gt; passingScores3 = scores.Where(score =&amp;gt; score &amp;gt;= 60);&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Func&amp;lt;&amp;gt; has 5 overloads:&lt;/p&gt;
&lt;p&gt;Func&amp;lt;TResult&amp;gt;&lt;br /&gt;
Func&amp;lt;T, TResult&amp;gt;&lt;br /&gt;
Func&amp;lt;T1, T2, TResult&amp;gt;&lt;br /&gt;
Func&amp;lt;T1, T2, T3, TResult&amp;gt;&lt;br /&gt;
Func&amp;lt;T1, T2, T3,  T4, TResult&amp;gt;&lt;/p&gt;
&lt;p&gt;In best coding practices, what are the maximum number of parameters a function should have? Well the designers of the Func&amp;lt;&amp;gt; delegate believe that it's four and I don't disagree with them. I am guilty of using more than four but that's mostly out of laziness of writing and populating a class to pass instead of the parameters.&lt;/p&gt;</description></item><item><title>JavaScript library management in browsers</title><link>http://guyellisrocks.com/coding/javascript-library-management-in-browsers/</link><pubDate>Fri, 06 Nov 2009 17:20:40 GMT</pubDate><guid isPermaLink="true">http://guyellisrocks.com/coding/javascript-library-management-in-browsers/</guid><dc:creator>guy ellis</dc:creator><slash:comments>0</slash:comments><category domain="http://guyellisrocks.com/coding/">coding</category><description>&lt;p&gt;Yesterday &lt;a href="http://googlecode.blogspot.com/2009/11/introducing-closure-tools.html"&gt;Google introduced its Closure Tools&lt;/a&gt; which includes its &lt;a href="http://code.google.com/closure/library"&gt;Closure Library&lt;/a&gt;. Google's &lt;a href="http://code.google.com/apis/ajaxlibs/documentation/"&gt;AJAX Libraries API page&lt;/a&gt; lists a bunch of common JavaScript libraries which include jQuery, Prototype, Scriptaculous, MootTools, Dojo, SWFObject (never heard of this one), and YUI.&lt;/p&gt;
&lt;p&gt;One of the advantages of using Google's content distribution network (CDN) for JavaScript libraries is that if someone visiting your site had previously visited another site which used the same JavaScript library from Google's CDN then that library will already be cached and your site will load faster. This is great but I believe that things could be even better. The problem is that you might be using a different CDN to other sites and will not benefit from this caching.&lt;/p&gt;
&lt;p&gt;Browsers should be able to manage a library of common JavaScript libraries along with their versions. Your JavaScript code should be able to ask for a particular library and version and the browser should have had it installed when the browser was installed or if released after the initial installation then installed with regular browser updates.&lt;/p&gt;</description></item><item><title>Optimizing a custom Trim() function in C#</title><link>http://guyellisrocks.com/coding/optimizing-a-custom-trim-function-in-c/</link><pubDate>Thu, 05 Nov 2009 17:15:00 GMT</pubDate><guid isPermaLink="true">http://guyellisrocks.com/coding/optimizing-a-custom-trim-function-in-c/</guid><dc:creator>guy ellis</dc:creator><slash:comments>4</slash:comments><category domain="http://guyellisrocks.com/coding/">coding</category><description>&lt;p&gt;I needed to write a Trim() function that removed anything that wasn't a digit from the beginning and end of a string. What usually happens when I write a blog entry like this is that someone posts a comment a few days later saying &amp;quot;hey, you didn't need to write that, it's already in the .NET library.&amp;quot; If it is, I haven't been able to find it.&lt;/p&gt;
&lt;p&gt;Here is my TrimNonDigits() function first attempt:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;protected string TrimNonDigits_v1(string text)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; while (text.Length &amp;gt; 0 &amp;amp;&amp;amp; !Char.IsDigit(text, 0))&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; text = text.Substring(1);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; while (text.Length &amp;gt; 0 &amp;amp;&amp;amp; !Char.IsDigit(text, text.Length - 1))&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; text = text.Substring(0, text.Length - 1);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return text;&lt;br /&gt;
}&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Now this function works and for what I needed it for (trivially short strings) it would do the job. But it is my intention to add it to a string extension library and I had a fear that someone would pass in an enormous string and with all the Substring() operations creating new strings this may become extremely inefficient.&lt;/p&gt;
&lt;p&gt;To see how inefficient this function was I wrote another unit test to specifically measure the speed at which the code ran. Here is that unit test:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;[TestMethod]&lt;br /&gt;
public void trim_non_digits_big_text()&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; int repeat = 10000;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; UnitTestDerived utd = new UnitTestDerived();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; string lotsOfCharacters = String.Join(&amp;quot;&amp;quot;, Enumerable.Repeat(&amp;quot;abcdef&amp;quot;, repeat).ToArray());&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; string text = lotsOfCharacters + &amp;quot;1&amp;quot; + lotsOfCharacters;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; string expected = &amp;quot;1&amp;quot;;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; string actual = utd.TrimNotDigits(text);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.AreEqual(expected, actual);&lt;br /&gt;
}&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The unit test passes but takes 21 seconds to run. Although extremely unlikely that this amount of non-digit-text on either side of a number might appear it's still a valid use case so the code needed reworking so that the Substring() function was only called once. This is the resulting change to the code:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;protected string TrimNonDigits(string text)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; int start = 0, end = text.Length - 1;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; while (text.Length &amp;gt; start &amp;amp;&amp;amp; !Char.IsDigit(text, start))&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; start++;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (start != end)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while (end &amp;gt; start &amp;amp;&amp;amp; !Char.IsDigit(text, end))&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end--;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return text.Substring(start, 1 + end - start);&lt;br /&gt;
}&lt;br /&gt;
&lt;/strong&gt;&lt;br /&gt;
The unit test runs against this new function in under 1 second. That's a dramatic difference and good demonstration for the case of not using Substring() repeatedly in a loop if you can help it.&lt;/p&gt;
&lt;p&gt;A side note. I also had several other unit tests that checked the validity of the results of the algorithm before I did the optimization. These included the testing of edge cases and extremes. This made the optimization refactor a cinch because I was fairly confident at the end that the algorithm will work in all situations.&lt;/p&gt;</description></item><item><title>MultiThread testing for speed</title><link>http://guyellisrocks.com/coding/multithread-testing-for-speed/</link><pubDate>Tue, 03 Nov 2009 23:58:51 GMT</pubDate><guid isPermaLink="true">http://guyellisrocks.com/coding/multithread-testing-for-speed/</guid><dc:creator>guy ellis</dc:creator><slash:comments>2</slash:comments><category domain="http://guyellisrocks.com/coding/">coding</category><description>&lt;p&gt;I recently wrote this little test program to validate that multi-threading was working the way I expected it to.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;class Program&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; private delegate void funcs();&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; static void Main(string[] args)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; funcs[] functions = new funcs[] &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new funcs(MultiThreadTest), &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new funcs(SingleThreadTest) &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (funcs function in functions)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DateTime startTime = DateTime.Now;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i = 0; i &amp;lt; 10; i++)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; function();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while (ThreadWorker.ThreadCount &amp;gt; 0)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Thread.Sleep(1);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(&amp;quot;{0} time taken: {1}&amp;quot;, &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; function.Method.Name, DateTime.Now - startTime);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.ReadLine();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; private static void MultiThreadTest()&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ThreadWorker threadWorker = new ThreadWorker();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ThreadStart threadDelegate = &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new ThreadStart(threadWorker.Runner);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Thread newThread = new Thread(threadDelegate);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; newThread.Start();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; private static void SingleThreadTest()&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ThreadWorker threadWorker = new ThreadWorker();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; threadWorker.Runner();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class ThreadWorker&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public static int ThreadCount = 0;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public ThreadWorker()&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ThreadCount++;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public void Runner()&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IEnumerable&amp;lt;string&amp;gt; strings = &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Enumerable.Repeat(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @&amp;quot;the not so quick brown fox was &lt;br /&gt;
caught by the hen and eaten with eggs&amp;quot;, 50);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string text = String.Join(&amp;quot; &amp;quot;, &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strings.SelectMany(a =&amp;gt; a.Split()).ToArray());&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i = 0; i &amp;lt; 1000; i++)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Do some random LINQ stuff to occupy the processor&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string[] list = text.Split(' ');&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string[] l2 = list.Distinct().ToArray();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; l2 = list.OrderBy(a =&amp;gt; a).ToArray();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; l2 = list.OrderByDescending(a =&amp;gt; a).ToArray();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ThreadCount--;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
}&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I tested this bit of code by running it four times on each of two machines.&lt;/p&gt;
&lt;p&gt;The first was a dual-core and the single-threaded-test took an average of 33.4 seconds and the multi-threaded-test 17.8 seconds. This makes the multi-threaded part 1.9 times faster which is about what you'd expect if you allow two processors to work on the problems in parallel.&lt;/p&gt;
&lt;p&gt;The second machine was a quad core with hyper-threading so essentially eight cores. This took an average of 29.3 seconds for the single-threaded-test and 4.6 seconds for the multi-threaded-test. An improvement factor of 6.4, not as close to 8 as I was expecting but not that far off. If anybody knows why the eight cores do not come as close to an eight-times factor as the two cores came to a two-times factor I'd love to hear from you in the comments.&lt;/p&gt;
&lt;p&gt;The two processors were:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Intel Core 2 CPU 6400 @ 2.13 GHz&lt;/li&gt;
    &lt;li&gt;Intel Xeon CPU L5410 @ 2.33GHz&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Something that I found interesting was that the slower processor ran 1.65 times faster than the fast processor when taking advantage of multi-threading. This has important implications for the software that you write. The single-threaded test ran 1.14 times (14%) faster on the faster processor. However, the multi-threaded code on the slower processor runs 65% faster than the single-threaded code on the faster processor.&lt;/p&gt;
&lt;p&gt;If you're looking for a performance boost there may be more performance in multi-threaded code than in a faster processor. In fact, processor speed is probably not what you're looking for. The best combination would be multi-threaded code on multi-core boxes.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description></item></channel></rss>
