Performance Iterating Generic Lists

C#, C# Language 5 Comments »

There are 3 obvious ways of iterating through each item in a generic list, but which is the most efficient.

  1. using a for statement
  2. using a foreach statement
  3. using the List.ForEach method with a delegate

 

I created the following simple application to test the differences:

    public partial class Form1 : Form

    {
        List<ListItem> items = new List<ListItem>();
        ProfileTimer timer = new ProfileTimer();
 
        public Form1()
        {
            InitializeComponent();
        }
 
        private void buttonAllocate_Click(object sender, EventArgs e)
        {
            int itemCount = (int)numericUpDown1.Value;
            textBox1.Clear();
            textBox1.AppendText("Allocating " + itemCount.ToString() + " items.\n");
            items.Capacity = itemCount;
            timer.Start();
            for (int i = 0; i < itemCount; i++)
            {
                items.Add(new ListItem());
            }
            timer.End();
            textBox1.AppendText("Took:" + timer.TimeTaken().ToString() + "\n");
        }
 
        private void buttonForLoop_Click(object sender, EventArgs e)
        {
            textBox1.AppendText("----------------------------------------------\n");
            textBox1.AppendText("Iterating with for loop\n");
            timer.Start();
            int itemCount = items.Count;
            for (int i = 0; i < itemCount; i++)
            {
                items[i].Value++;
            }
            timer.End();
            textBox1.AppendText("Took:" + timer.TimeTaken().ToString() + "\n");
        }
 
        private void ButtonForEachStatement_Click(object sender, EventArgs e)
        {
            textBox1.AppendText("----------------------------------------------\n");
            textBox1.AppendText("Iterating with foreach\n");
            timer.Start();
            foreach(ListItem item in items)
            {
                item.Value++;
            }
            timer.End();
            textBox1.AppendText("Took:" + timer.TimeTaken().ToString() + "\n");
        }
 
        private void buttonForEachDelegate_Click(object sender, EventArgs e)
        {
            textBox1.AppendText("----------------------------------------------\n");
            textBox1.AppendText("Iterating with foreach delegate\n");
            timer.Start();
            items.ForEach(delegate(ListItem item)
                {
                    item.Value++;
                }
            );
            timer.End();
            textBox1.AppendText("Took:" + timer.TimeTaken().ToString() + "\n");
        }
    }

 

Where the list item is defined as

    class ListItem
    {
        public int Value;
    }

 

The following results were obtained in Seconds 




No of items in the list For Statement ForEach Statement ForEach Delegate
100,000 0.000909729 0.00154351 0.001170701
1,000,000 0.009031616 0.015998993 0.011646201
10,000,000 0.093305468 0.160015975 0.114651431

Tests run on an Intel Pentium Dual Core 3.2GHz  with 3Gb Ram.

As we can see the choice of iterator makes very little difference when there are a small amount of items in the list, but as we move upto iterating lists containing hundreds of thousands of items, there are some performance improvements between the methods.

The For statement out performs the rest, 71% faster than the ForEach Statement, but it should be noted that the itemcount check in the for loop needs to be stored and not checked on each iteration. i.e. don’t use for(int i=0; i<items.count;i++) If the items.count is called on every iteration the perfromace is the same as the ForEach Delegate.

The ForEach delegate comes in second, 39% faster than the ForEach Statement.

Conclusion

For most applications there is not much performance impact in the iteration times, but if time is critical or you have nested iterations then you should be using a basic for loop (BUT rememeber to store the limit in an integer and use in the comparison and DONT allocate a new ListItem variable in the iterator). 

Personally, having come from a delphi background and tending to use the iterator pattern, I’ll be using the ForEach delegate. I think it reads nicer and gets a reasonable performance.

Receive Key Messages irrespective of Key Modifiers

C#, Component Development, Win Forms No Comments »

As covered in a previous article, you can overrride the IsInputKey method on a control to inform winforms that you require keyboard event notification for special keys like tabe and cursor keys which are used but the hosting form for control navigation.

When writing a control, I was trying to capture the SHIFT - Right Cursor combination.  I already had the following implementation in IsInputKey

                        switch (keyData)

            {
                case Keys.Up:
                case Keys.Down:
                case Keys.Left:
                case Keys.Right:
                case Keys.Home:
                case Keys.End:
                    {
                        return true;
                    }
            }
            return base.IsInputKey(keyData);
 

However, althought control-Right and Alt-Right events came through Shift-Right wouldn’t.  These were passed to the base implementation which returned true to be handled by the control but fals for the shift right.

So to force the processing of keys irrespective of the key modifiers simply chnage the case statement to read

            switch (keyData & ~Keys.Modifiers)

 Which removes and modifier bit flags from the keydata fro the switch comparison.

How to determine if a control or one of it’s child controls has focus

C#, Component Development, Win Forms 1 Comment »

Focus returns a boolean to indicate whether or not a control has focus or not, but when trying to paint your own focus rectangle in your control and you have allowed your controls scrollbars to accept focus, then the Focus property will return false. 

Instead of using Focus, check the ContainsFocus property that returns true if the control or a child control has focus.

Notifying the Collection Editor of changes

C#, Component Development, Win Forms No Comments »

When you are building your own collections of objects it is common to use an overridden ToString implementation to display some property of your object in the collection editor instead of the full class name which is the default.

For example, when developing a Column collection, I override the ToString() to return the Columns caption.  However, when the caption property of my column is updated in the standard collection editor, the respective item in the list of items in the collection editor is not updated. 

The collection editor can be notified to refresh it’s properties and therefore the list by adding a RefreshProperties attribute to the property that causes the required change.

e.g.

    public class TreeColumn
    {
        private String _Caption;
 
        [RefreshProperties(RefreshProperties.All)]
        [Browsable(true)]
        [Description("The Caption for the column")]
        public String Caption
        {
            get { return _Caption; }
            set { _Caption = value; }
        }
 
        public override string ToString()
        {
            if (!String.IsNullOrEmpty(_Caption))
                return _Caption;
            return base.ToString();
        }
    }

Create a string of Repeating Characters

C#, C# Language No Comments »

Creating a string of repeating characters is really simple in c#, however it is not in the obvious place you would look.  First I tried the String class, hoping there would be a static like String.RepeatString, and even looked in the StringBuilder class.  Eventually found it in a very logical place when you think about it, the String classes constructor.

String (Char, Int32)

So to create a repeating string simply use

String myString = new String('x', 12);

which will create a string of x’s 12 characters long.

WP Theme &Design by minus19.com & Icons
Entries RSS Comments RSS Log in