Click here to Skip to main content
Licence 
First Posted 30 Apr 2003
Views 83,951
Bookmarked 25 times

Iteration Performance in .NET

By | 20 May 2003 | Article
Article on the relative performance of various methods of iterating through large amounts of data.

Introduction

I’ve been implementing numerical libraries in .NET and have come to some conclusions about iteration performance. My classes have to hold a large amount of data and be able to iterate through that data as quickly as possible. In order to compare various methods, I created a simple class called Data that encapsulates an array of doubles.

Method #1: Enumeration

Data implements IEnumerable. It contains GetEnumerator which returns its own DataEnumerator, an inner class.
public DataEnumerator GetEnumerator() 
    {
      return new DataEnumerator( this );
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
      return GetEnumerator();
    }
  }
	
…
  public struct DataEnumerator : IEnumerator
  {
    private Data internal_;
    private int index_;

    public DataEnumerator( Data data ) 
    {
      internal_ = data;
      index_ = 1;
    }

    public double Current
    {
      get
      {
        return internal_.Array[index_];
      }
    }

    object IEnumerator.Current 
    {
      get
      {
        return Current;
      }
    }
  
    public bool MoveNext()
    {
      index_++;
      if ( index_ >= internal_.Array.Length ) 
      {
        return false;
      }
      return true;
    }

    public void Reset()
    {
      index_ = -1;
    }
  }
}
…

Method #2: Indexing

I implemented an index operator on the class which simply calls the index operator on the array.

    public double this[int position]
    {
      get
      {
        return array_[position];
      }
    }

Method #3: Indirect Array

I created a property to access the array.

    public double[] Array
    {
      get 
      {
        return array_;
      }
    }

When iterating, I called the Array property and then its index operator.

          d = data.Array[j];

Method #4: Direct Array

I created a reference to the array.

        double[] array = data.Array;

Then, I iterate through that reference.

          d = array[j];

Method #5: Pointer Math

Finally, I tried improving performance by iterating through the array in Managed C++ using pointer manipulation.

        static void iterate( Data& data )
        {
          double d;
          double __pin* ptr = &( data.Array[0] );
          for ( int i = 0; i < data.Array.Length; i++ ) 
          {
            d = *ptr;
            ++ptr;
          }
        }

I called it this way:

        Pointer.iterate( data );

Conclusions

To test the different methods, I allocated 1,000,000 doubles into an array and indexed over all of them. I repeated this 1,000 times to minimize randomness. Here are the results...

Results

Enumeration is always slow. That’s not surprising as I’m using a general data structure to hold the doubles. The three operator/property methods differed very slightly. These are probably all optimized similarly. Using pointer math to traverse over the raw data was significantly faster. This is probably due to the fact that there’s no bounds checking. In summary, if you have large amounts of data and performance is critical, consider using managed C++.

Acknowledgements

Thanks to Mark Vulfson of ProWorks for tips on using Flipper Graph Control. Also, to my colleagues Ken Baldwin and Steve Sneller at CenterSpace Software.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Trevor Misfeldt

CEO
CenterSpace Software
United States United States

Member

Trevor has held demanding development positions for a variety of firms using C++, Java, .NET, and other technologies, including Rogue Wave Software, CleverSet, and ProWorks. He is coauthor of The Elements of Java Style , The Elements of C++ Style, and The Elements of C# Style, published by Cambridge University Press. He has also served on a course advisory board of the University of Washington. His teams have won the JavaWorld "GUI Product of the Year" and XML Magazine "Product of the Year" awards. Trevor holds a BSc in Computer Science from the University of British Columbia and a BA in Economics from the University of Western Ontario.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralNice PinmemberAnthony_Yio15:51 13 Oct '03  
GeneralEnumerations PinmemberPaul Evans23:19 26 May '03  
GeneralRe: Enumerations Pinsussasm4311:21 28 May '03  
GeneralUpdate PinmemberTrevor Misfeldt5:55 7 May '03  
GeneralRe: Update Pinmemberdog_spawn16:22 21 May '03  
GeneralRe: Update PinsussMorten Sparding22:28 11 Mar '05  
One simple explanation for the relative poor performance for the Enumeration is the number of statements that is executed on each iteration. This can be reduced by changing the MoveNext method to read:
 
return (internal_.Array.Length > ++index_);
 
In all other iteration test you assume to know the size of the Data array by writing:
 
for ( int j = 0; j < size; j++ )
 
which is unfair, so change it to:
 
for (int j = 0; j < data.Array.Length; j++)
 
All in all this gives me:
 
Enumeration: 5,125 seconds
Indexing: 3,531 seconds
Indirect Arrays: 3,89 seconds
Direct Arrays: 3,75 seconds
Poiner: N/A
 
Better but still a difference !
Generalunsafe C# PinmemberJohn Rayner5:04 7 May '03  
GeneralRe: unsafe C# PinmemberTrevor Misfeldt5:53 7 May '03  
GeneralEnumeration performance PinmemberJames T. Johnson1:59 2 May '03  
GeneralRe: Enumeration performance PinsussTrevor Misfeldt4:29 2 May '03  
GeneralRe: Enumeration performance PinmemberAndy Gray6:23 6 May '03  
GeneralRe: Enumeration performance PinmemberJedrekM8:35 20 Jun '03  
GeneralRe: Enumeration performance PinmemberTrevor Misfeldt9:46 20 Jun '03  
GeneralRe: Enumeration performance PinmemberOscar Bowyer3:44 6 May '03  
GeneralRe: Enumeration performance PinmemberJames T. Johnson4:36 6 May '03  
GeneralRe: Enumeration performance Pinmembermikasa3:11 22 May '03  
GeneralRe: Enumeration performance PinmemberJames T. Johnson9:11 22 May '03  
GeneralRe: Enumeration performance Pinmembermikasa9:18 22 May '03  
GeneralRe: Enumeration performance PinmemberJames T. Johnson9:29 22 May '03  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120528.1 | Last Updated 21 May 2003
Article Copyright 2003 by Trevor Misfeldt
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid