Tuesday, 29 November 2011

csharp, process the items of Dictionary serial and faster

The Dictionary type abstracts out its looping logic into enumerators: these are accessed through the foreach loop and the GetEnumerator method. In this article, we demonstrate the GetEnumerator method, which exhibits better performance than the foreach loop.

Examples

Let's examine the most common and easiest way to loop through a Dictionary instance. The foreach loop here actually compiles into intermediate language that uses the GetEnumerator method, MoveNext, and Current, as well as a try/finally block.
Finally
Looping over Dictionary with foreach [C#]

static int A(Dictionary<string, int> d)
{
    int a = 0;
    foreach (var pair in d)
    {
 a += pair.Value;
    }
    return a;
}
Next, this method demonstrates the GetEnumerator and MoveNext methods and the Current property directly. This code is compiled to the same intermediate language except the try/finally block is absent.
Looping over Dictionary with GetEnumerator [C#]

static int B(Dictionary<string, int> d)
{
    int b = 0;
    var enumerator = d.GetEnumerator();
    while (enumerator.MoveNext())
    {
 var pair = enumerator.Current;
 b += pair.Value;
    }
    return b;
}
What's the difference? The difference between method A and method B is that method B is harder to read and it also omits the try/finally construct that was added by the C# compiler. Therefore, the next question is, "Which one is faster?"
Performance optimization

Performance

I tested the two methods of looping through Dictionary instances in a test program. The harness used is available in the link below. The dictionary initialization code is shown below as well, and finally we see that method B was faster by a fairly constant amount.

 
Dictionary initialization [C#]

var d = new Dictionary<string, int>();
d["one"] = 1;
d["two"] = 2;
d["three"] = 3;
d["four"] = 4;
d["five"] = 5;

Results

Method A (foreach):       92.07 ns
Method B (GetEnumerator): 88.53 ns

Summary

Using GetEnumerator directly is somewhat faster than using the foreach loop on Dictionary. The finally statement actually calls the enumerators Dispose method, which has an empty implementation. Thus, GetEnumerator is worth considering as a way to improve Dictionary performance in certain C# programs.

No comments:

Post a Comment