Current .Net Version: 2.0.50727
Home
Articles
C# & .Net Framework Reference
Practice C# Online
XML Web Services
RSS Feeds
Code Snippets
T-SQL Scripts
Videos
Valuable Links
Contact Us
Mike's C#, VS.NET and SQL Blog




ROR XML Info.
C# 2.0 Iterators are Faster, but not that Faster
Author: Michael G.     Last Updated:9/29/2005 8:03:35 PM
Category(ies): C# 2.0, .Net Framework 2.0
Description: C# 2.0 iterators are fast, but not as fast as custom designed iterators that implement IEnumerator. Check out these performance tests.
  Add & View Comments About this Article

Tested with Microsoft Visual C# 2005 Beta 1, .Net 2.0.40607.42

C# 2.0 provides us with a way to implement IEnumerator for compatilibity with foreach-in collection access: the yield keyword. yield now delivers what GetEnumerator did with previous versions of .Net, and it's much faster too!

However, I've found that building your own custom IEnumerator classes will provide you with a faster result than with any of the other two standard GetEnumerator/IEnumerator patterns.

In a test involving three different classes that implement three different ways to iterate through a collection of one million strings, it's clear that using custom-built iterators are much faster. Here are the results of my test: .Net 1.0/1.1 Iterator Time: 296 milliseconds .Net 2.0 Iterator Time: 93 milliseconds. .Net Custom Iterator Time: 46 milliseconds. Press any key to continue... Console application that tests for TimeSpans between 3 enumerable collection classes/methods: namespace Comparison1020Iterators { class Program { static void Main(string[] args) { My10CollectionClass mc10 = new My10CollectionClass(); DateTime dt10 = DateTime.Now; foreach (String str in mc10) { // Do nothing...continue... } TimeSpan ts10 = DateTime.Now.Subtract(dt10); My20CollectionClass mc20 = new My20CollectionClass(); DateTime dt20 = DateTime.Now; foreach (String str in mc20) { // Do nothing...continue... } TimeSpan ts20 = DateTime.Now.Subtract(dt20); MyCustomCollectionClass mcCustom = new MyCustomCollectionClass(); DateTime dtCustom = DateTime.Now; foreach (String str in mcCustom) { // Do nothing...continue... } TimeSpan tsCustom = DateTime.Now.Subtract(dtCustom); Console.WriteLine(".Net 1.0/1.1 Iterator Time: {0} milliseconds.", ts10.Milliseconds.ToString()); Console.WriteLine(".Net 2.0 Iterator Time: {0} milliseconds.", ts20.Milliseconds.ToString()); Console.WriteLine(".Net Custom Iterator Time: {0} milliseconds.", tsCustom.Milliseconds.ToString()); Console.WriteLine("Press any key to continue..."); Console.ReadKey(); } } public class My20CollectionClass { private String[] m_Strings; public My20CollectionClass() { this.m_Strings = new String[1000000];; } public System.Collections.IEnumerator GetEnumerator() { foreach (String str in this.m_Strings) yield return str; } } public class My10CollectionClass { private String[] m_Strings; public My10CollectionClass() { this.m_Strings = new String[1000000];; } public System.Collections.IEnumerator GetEnumerator() { return this.m_Strings.GetEnumerator(); } } public class MyCustomCollectionClass : System.Collections.IEnumerator { private String[] m_Strings; private int m_CurrentIndex = -1; public MyCustomCollectionClass() { this.m_Strings = new String[1000000];; } public bool MoveNext() { bool bln = true; this.m_CurrentIndex++; if (this.m_CurrentIndex > this.m_Strings.Length - 1) bln = false; return bln; } public void Reset() { this.m_CurrentIndex = -1; } public Object Current { get { if (this.m_CurrentIndex == -1) this.MoveNext(); return this.m_Strings[this.m_CurrentIndex]; } } public System.Collections.IEnumerator GetEnumerator() { return this; } } }

Comments Click Here to Add your Comment
By rawCoder @ 4/29/2005 11:01:18 AM

A little explaination for why this difference exists will be highly appreciated.

By Michael G. @ 4/30/2005 11:16:04 AM

I think that's something only Microsoft can answer (since it's an intrinsic code reason).
By TommyV @ 5/4/2005 3:16:32 PM

Not that faster?  By your numbers, 2.0 looks to be over three times faster.  Am I missing something? =)

By Michael G. @ 5/8/2005 10:43:25 AM

Net 1.0/1.1 Iterator Time: 296 milliseconds
.Net 2.0 Iterator Time: 93 milliseconds.
.Net Custom Iterator Time: 46 milliseconds.

If you look at the numbers, you'll see that custom built iterators are faster than .Net 2.0 iterators. That was really my point, not that 2.0 iterators are faster than 1.0 iterators.
By peter @ 11/2/2005 3:40:08 AM

>this.m_Strings = new String[1000000];

so wasteful!
By Mike G. @ 12/8/2005 6:26:02 PM

RE: this.m_Strings = new String[1000000];

It's a test - not something you'd want to write for a production application.
By Chris Mullins @ 8/18/2006 2:04:25 PM

Your C# .Net 2.0 Iterator is still going through a bit more work than it needs to. The enumerator you're using is object base, which means it's being cast to a string when it's used.

Replace:
public IEnumerator GetEnumerator()

With the Generic Version:
public IEnumerator>string< GetEnumerator()

This will help a bit with strong typing, and may show a modest gain.
By geaalvdm @ 10/20/2007 4:41:40 AM

>a href="http://kqryqrge.com"<dhdihwlg>/a<  [URL=http://sfkgntue.com]dqgwagpl[/URL] ; tthgkwzr http://zzxtykhb.com fleqgzrk vnvakkex
By fkdb aqxu @ 1/14/2008 1:15:32 PM

qrynlhdf sjugcmbeh fmazeglpo ywchgroa mgfiz kajsnio puhmw
By fkdb aqxu @ 1/14/2008 1:16:39 PM

qrynlhdf sjugcmbeh fmazeglpo ywchgroa mgfiz kajsnio puhmw
By fkdb aqxu @ 1/14/2008 1:16:58 PM

qrynlhdf sjugcmbeh fmazeglpo ywchgroa mgfiz kajsnio puhmw
By nzndujhb @ 1/30/2008 5:47:32 AM

irslbksx http://cbzlqkvd.com rkcckloj lffhrslt  [URL=http://lihwiygp.com]ifsxrurq[/URL] ; >a href="http://vrunnkqc.com"<nogeedqw>/a<
By aziyafxm @ 4/29/2008 11:52:12 PM

>a href="http://wxeufjfj.com"<nnoattss>/a<  hqjbzevg http://fhuvihys.com fysljbig absifalz  [URL=http://ozftrpwd.com]cxdeyosy[/URL]
 
COPYRIGHT/DISCLAIMER | CONTACT US