Another reason I love this list so much.
________________________________ From: [email protected] [mailto:[email protected]] On Behalf Of Greg Harris Sent: Thursday, 20 May 2010 3:21 PM To: ozDotNet Subject: Re: How To do something every so often Hi Everyone, I think that this shows that we all have too much time on our hands! Our modern machines are so fast that this is an irrelevant question for all but the most compute intensive applications. The standard well known design pattern is to use the modulus (%) function. if ( (i % lTestPoint) == 0 ) Console.Write( "x" ); As about 80% of development cost is in maintenance, then keep it simple unless you really really need to change it for a good reason. So DON'T CHANGE THIS! I wrote a quick program to test this and got the result that it does not really matter which technique you use when you compare it to doing a little bit of real work inside the loop. In some more detail... The program had a tight loop going from zero to 268,435,456 (0x10000000) and outputting an "x" every 16,777,215 (0xffffff) times through the loop. Tests results were: * Using modulus (%) function, time = 3.20 seconds (the slowest) * Using separate counter with equals (==) test, time = 1.81 seconds * Using separate counter with greater than equals (>=) test, time = 1.79 seconds * Using Boolean logic on the base counter, time = 1.64 seconds (the fastest test) * Not test at all, time = 1.01 seconds * Doing some real work and not doing the test at all, time = 9.93 second This shows what I would expect: * Not doing the test is the fastest. * A Boolean logic test is the fastest way of actually doing the test. * A separate counter is a little slower, but effectively the same time. * It does not matter if you test for equal (==) or greater than or equal (>=) (the difference is in the third decimal place) * Yes modulus function (%) is the slowest * But all irrelevant compared to doing some real simple work in the loop The modulus function (%) took 1.55 seconds more than the Boolean logic over 268,435,456 iterations, it has taken me about an hour to write this test program and email, the modulus function could have been run more than 300 Billion times in this time! Test program output lEndPoint: 268435456 lTestPoint: 16777215 Start Test 1: using Mod (%) xxxxxxxxxxxxxxxxx Done 00:00:03.1981829 Start Test 2: using a separate counter test is == xxxxxxxxxxxxxxxx Done 00:00:01.8081034 Start Test 3: using a separate counter test is >= xxxxxxxxxxxxxxxx Done 00:00:01.7921025 Start Test 4: using boolean logic on the base counter xxxxxxxxxxxxxxxx Done 00:00:01.6380937 Start Test 5: No test at all Done 00:00:01.0070576 Start Test 6: No test at all, but doing some real work Done 00:00:09.9345682 Test program static void Main(string[] args) { DateTime lStartTime ; DateTime lEndTime ; TimeSpan lDelta ; long lCounter ; long lEndPoint = 0x10000000; // 268,435,456 long lTestPoint = 0xffffff ; // 16,777,215 double lSum = 0 ; // sum of the square roots (the work test#6 only) Console.WriteLine( "lEndPoint: " + lEndPoint .ToString() ); Console.WriteLine( "lTestPoint: " + lTestPoint.ToString() ); Console.WriteLine( "Start Test 1: using Mod (%)" ); lStartTime = DateTime.Now; for ( long i = 0; i<=lEndPoint; i++ ) { if ( (i % lTestPoint) == 0 ) Console.Write( "x" ); } Console.WriteLine(); lEndTime = DateTime.Now; lDelta = lEndTime - lStartTime; Console.WriteLine( "Done " + lDelta.ToString() ); Console.WriteLine(); Console.WriteLine( "Start Test 2: using a separate counter test is ==" ); lCounter = 0; lStartTime = DateTime.Now; for ( long i = 0; i<=lEndPoint; i++ ) { lCounter++; if ( lCounter == lTestPoint ) { Console.Write( "x" ); lCounter = 0; } } Console.WriteLine(); lEndTime = DateTime.Now; lDelta = lEndTime - lStartTime; Console.WriteLine( "Done " + lDelta.ToString() ); Console.WriteLine(); Console.WriteLine( "Start Test 3: using a separate counter test is >=" ); lCounter = 0; lStartTime = DateTime.Now; for ( long i = 0; i<=lEndPoint; i++ ) { lCounter++; if ( lCounter >= lTestPoint ) { Console.Write( "x" ); lCounter = 0; } } Console.WriteLine(); lEndTime = DateTime.Now; lDelta = lEndTime - lStartTime; Console.WriteLine( "Done " + lDelta.ToString() ); Console.WriteLine(); Console.WriteLine( "Start Test 4: using boolean logic on the base counter" ); lStartTime = DateTime.Now; for ( long i = 0; i<=lEndPoint; i++ ) { if ( (i & lTestPoint) == lTestPoint ) { Console.Write( "x" ); } } Console.WriteLine(); lEndTime = DateTime.Now; lDelta = lEndTime - lStartTime; Console.WriteLine( "Done " + lDelta.ToString() ); Console.WriteLine(); Console.WriteLine( "Start Test 5: No test at all" ); lStartTime = DateTime.Now; for ( long i = 0; i<=lEndPoint; i++ ) { // Do nothing } Console.WriteLine(); lEndTime = DateTime.Now; lDelta = lEndTime - lStartTime; Console.WriteLine( "Done " + lDelta.ToString() ); Console.WriteLine(); Console.WriteLine( "Start Test 6: No test at all, but doing some real work" ); lStartTime = DateTime.Now; for ( long i = 0; i<=lEndPoint; i++ ) { lSum += System.Math.Sqrt((double)i); } Console.WriteLine(); lEndTime = DateTime.Now; lDelta = lEndTime - lStartTime; Console.WriteLine( "Done " + lDelta.ToString() ); Console.WriteLine(); Console.ReadLine(); } ------------------------------------------------------------------------------------------------- To find out more about the Sunshine Coast Council, visit your local council office at Caloundra, Maroochydore, Nambour or Tewantin. Or, if you prefer, visit us on line at www.sunshinecoast.qld.gov.au This email, together with any attachments, is intended for the named recipient(s) only. Any form of review, disclosure, modification, distribution and or publication of this email message is prohibited without the express permission of the author. Please notify the sender immediately if you have received this email by mistake and delete it from your system. Unless otherwise stated, this email represents only the views of the sender and not the views of the Sunshine Coast Regional Council. maile 3_1_0
