![]() | |
![]() |
| | Thread Tools | Search this Thread | Display Modes |
#1
| |||
| |||
|
|
I'm trying to write a parser for a Interbase stored procedure and I want to identify the fastest way to go through a string one char at a time. As I'm really new to both c# and dotNet, I thought I'll share my findings and ask for comments: I found 4 different methods of going over the string one char at a time, and my results seem somewhat unexpected! [Method 1 - read directly from string - 100% timing] for (int i=0;i<str_len;i++) c = TestString[i] [Method 2 - read using StringBuilder - 200% timing] for (int i=0;i<str_len;i++) c = TestBuilder[i] [Method 3 - read using an CharEnumerator - 512% timing] ch.Reset(); while (ch.MoveNext()) c = ch.Current; [Method 4 - read using a foreach loop - 170% timing] foreach (char c2 in TestString) c = c2 After doing all those tests I ended up with lots of questions: 1) Why is the "foreach" loop slower then the "for" loop? 2) Why is the CharEnumerator so slow? Am I using this class properly? 3) Is my test method fair? (see attachment for my code) |
#2
| |||
| |||
|
|
Hi, The foreach loop will be slower in the case that you provide as it has a much greater overhead for what your trying to achieve. If however, your array/collection contained objects (just for arguments sake) and you were required to do some additional processing on the object. The foreach loop would start improving the performance (as well as maintainability by other developers) as the variable would contain a reference to the actual object allowing you to work on it directly. The for loop on the other hand would require you to constantly reference an offset into the collection each time you reference the object to modify a property or call a method. You could reduce this overhead in the for loop for this example by having a variable of the correct type and setting this in the first line of the for statement. This will close the gape of the timings. There are still some additional things that the foreach stament does to improve the stability of your code that you would not be doing in the for loop. The foreach will do the following: First of all it extracts the IEnumerator interface from the collection using GetEnumerator(). Then enters a while loop for the IEnumerator calling MoveNext(). This will then typecast the current enumerator (Current() ) to the Type specified by the variable then execute all your code. This block is then wrapped in a try.finally block to ensure if anything goes wrong it can free up the Enumerator interface if it implements the IDisposable interface. One thing you have to consider is the performance gain against the maintainability as mentioned in the other posts. It's one thing to have really optimised code but the price you pay comes when you or some one else has to maintain it or modify it some months/years down the line. Having said that a for loop is a basic operation that developers should have no problem understanding. Are we talking about milliseconds increase in performance for a cost of 30min + development time 4 months down the line trying to work out how to modify it. - Mike --------------------------------------------------------------------------------- a href="http://www.cogitar.net"> Cogitar Software. (www.cogitar.net) /a http://www.web-dominion.co.uk Web-Dominion. (Web Design and hosting ) --------------------------------------------------------------------------------- "Cosmin Prund" <cosminREMOVE (AT) adicomsft (DOT) NOSPAM.ro> wrote in message news:uXrtQsp6FHA.3276 (AT) TK2MSFTNGP10 (DOT) phx.gbl... I'm trying to write a parser for a Interbase stored procedure and I want to identify the fastest way to go through a string one char at a time. As I'm really new to both c# and dotNet, I thought I'll share my findings and ask for comments: I found 4 different methods of going over the string one char at a time, and my results seem somewhat unexpected! [Method 1 - read directly from string - 100% timing] for (int i=0;i<str_len;i++) c = TestString[i] [Method 2 - read using StringBuilder - 200% timing] for (int i=0;i<str_len;i++) c = TestBuilder[i] [Method 3 - read using an CharEnumerator - 512% timing] ch.Reset(); while (ch.MoveNext()) c = ch.Current; [Method 4 - read using a foreach loop - 170% timing] foreach (char c2 in TestString) c = c2 After doing all those tests I ended up with lots of questions: 1) Why is the "foreach" loop slower then the "for" loop? 2) Why is the CharEnumerator so slow? Am I using this class properly? 3) Is my test method fair? (see attachment for my code) |
![]() |
| Thread Tools | Search this Thread |
| Display Modes | |
| |