Saturday, December 10, 2011

Performance of C# 4.0 dynamic vs Dictionary vs object[]

Did you know what the performance impact of using the ExpandoObject is?
Here is a quick performance test generating an array of 2’000’000  items which have exactly one integer property “Index” and then calculate the average of that integer.

void Main()
{
    var count =  2000000;
    
    var dicos = GetDictionaries(count).ToArray();
    var dicoAvg = dicos.Average(i => (int)i["Index"]);
    var expandos = GetExpandoObjects(count).ToArray();

    var expandoAvg = expandos.Average(i => i.Index);
    var anos = (from index in Enumerable.Range(1,count)
               select new { Index = index}).ToArray();
    var anosAvg = anos.Average(i => i.Index);    
    var objects = GetObjects(count).ToArray();
    var objectAvg = objects.Average(i => (int)i[0]);


}


IEnumerable<IDictionary> GetDictionaries(int count)
{
    return from index in Enumerable.Range(1,count)
           select new Dictionary<string, object>() { {"Index", index} };
}

IEnumerable<dynamic> GetExpandoObjects(int count)
{
    foreach(var index in Enumerable.Range(1,count))
    {
        dynamic obj = new ExpandoObject();
        obj.Index = index;
        yield return obj;
    }
}
IEnumerable<object[]> GetObjects(int count)
{
    return from index in Enumerable.Range(1,count)
           select new object[] {index};
}

No surprise, the anonymous type is the fasted followed by the object array. Both, the ExpandoObject and the Dictionary must store a Key/Value pair internally and do a key lookup to return the requested “Index” value for the averaging function. Which structure should you use? I guess the answer depends on the degree of flexibility you need, but consider the performance impact.


Structure

ToArray()

Average

Dictionary

3069ms

179ms

ExpandoObject

2757ms

125ms

Object array

1215ms

37ms

Anonymous type

421ms

33ms





Any other ideas?

1 comment: