Struct Layouts Performance Tip

Most developers aware of that Structs needed to be in smaller size (16byte or less) so they can run efficiently as possible. If you are interested in how the Struct size contributes to better performance, please refer to this question. This post is about another less popular tip that may contribute to improve the efficiency of Structs.
Just a bit of back ground on Layouts:

The way you structure your code, for example the order you specify fields within a type, is not necessarily the same way the CLR organize those fields. For performance reasons, CLR can re-arrange those fields of a type any way it chooses. Using StructureLayoutAttribute attribute, you can explicitly tell CLR the way you want to organize your fields. If you don’t specify a StructureLayoutAttribute, the compiler selects the most appropriate layout it thinks best.

For Structs, C# compiler creates the LayoutType.Sequnetial by default. This means the fields should stay in the order defined by the programmer.

(Note: For Reference types C# compiler selects the LayoutType.Auto by default.)
Below is a C# Struct with no explicit layout and the corresponding generated IL.

image 1

The Structs are commonly used when interoperating with unmanaged code. Therefore the fields must stay in the order that programmer define for this to work. But most user defined value types/Structs you create have nothing to do with interoperability with unmanaged code. Therefore if you specify the LayoutKind.Auto, the runtime automatically decide the appropriate layout.

 

image2

If you do a quick benchmark on both layouts you see the LayoutKind.Auto is much faster than the LayoutKind.Sequential.

image3

Result–

(Time in milliseconds)

image4

 

(Config: .NET 4, x86, and Release build)
If you want to look at the sample code is below.

//uses LayoutKind.Sequence by default
   2:    publicstructStructSeq

   privatereadonlyByte mb;
   privatereadonlyInt16 mx;
   publicstringa;
   publicstringb;
   publicstringc;
   publicstringd;
}
>
[StructLayout(LayoutKind.Auto)]
publicstructStructAuto
{
    privatereadonlyByte mb;
    privatereadonlyInt16 mx;
    publicstringa;
    publicstringb;
    publicstringc;
    publicstringd;
}

Program
{
  voidMain()
    {
        StructSeq sq = newStructSeq();
        Stopwatch sw1 = newStopwatch();
        sw1.Start();
        for(inti = 0; i < 8000000; i++)
        {
            ProcessStructSeq(refsq);
        }
        sw1.Stop();
        Console.WriteLine("Struct LayoutKind.Sequence (default) {0}", sw1.Elapsed.TotalMilliseconds);

        StructAuto so = newStructAuto();
        Stopwatch sw2 = newStopwatch();
        sw2.Start();
        for(inti = 0; i < 8000000; i++)
        {
            ProcessStructAuto(refso);
        }
        sw2.Stop();
        Console.WriteLine("Struct LayoutKind.Auto (explicit) {0}", sw2.Elapsed.TotalMilliseconds);

        Console.ReadLine();
    }

    publicstaticvoidProcessStructSeq(refStructSeq structSeq)
    {
        structSeq.a = "1";
        structSeq.b = "2";
        structSeq.c = "3";
        structSeq.d = "4";
    }

    publicstaticvoidProcessStructAuto(refStructAuto structAuto)
    {
        structAuto.a = "1";
        structAuto.b = "2";
        structAuto.c = "3";
        structAuto.d = "4";
    }
}

Dynamic columns via DynamicObject

This might be obvious to some of you, but I thought of writing a small post, since it has a nice example of the usage of  .NET 4. DynamicObject.

Recently I had a requirement where I had to dynamically generate a tabular data (rows/cols) and use that data for Json serialization.

There are few ways of implementing this. The below example uses the .NET 4. DynamicObject to generate custom columns. I found this is quite easier and cleaner to implement than the tradition reflection based approach.

var columnsSet1 = new List<Col>() {new Col("row1Col1"),
new Col("row1Col2"), new Col("row1Col3")};
var columnsSet2 = new List<Col>() {new Col("row2Col1"),
new Col("row2Col2"), new Col("row2Col3")};

Dynamic columns via DynamicObject

This might be obvious to some of you, but I thought of writing a small post, since it has a nice example of the usage of .NET 4. DynamicObject.
Recently I had a requirement where I had to dynamically generate a tabular data (rows/cols) and use that data for Json serialization.
There are few ways of implementing this. The below example uses the .NET 4. DynamicObject to generate custom columns. I found this is quite easier and cleaner to implement than the tradition reflection based approach.

static Table GenerateData()
           {

               var columnsSet1 = new List<Col>() {new Col("row1Col1"), new Col("row1Col2"), new Col("row1Col3")};
               var columnsSet2 = new List<Col>() {new Col("row2Col1"), new Col("row2Col2"), new Col("row2Col3")};             

               var rows = new List<Row> {  new Row() { Cols = columnsSet1 },
                                           new Row() { Cols = columnsSet2 },

                                    };

               var rowList = new List<dynamic>();

               foreach (var row in rows)
               {
                   dynamic dynamicCol = new ColExpando(); //ColExpando derived from DynamicObject
                   var cols = row.Cols;

                   foreach (var col in cols)
                   {
                       dynamicCol.Column = col.Val;
                   }
                   rowList.Add(dynamicCol);
               }
               var tb = new Table { Data = rowList };
               return tb;
           }

        public class ColExpando: DynamicObject
        {
            private readonly Dictionary<string, object> members = new Dictionary<string, object>();
            private int colAppendIndex = 0;           

            public override bool TrySetMember(SetMemberBinder binder, object value)
            {

                   colAppendIndex++;
                    string key = binder.Name + colAppendIndex;

                    if (!members.ContainsKey(key))
                    {
                        members.Add(key, value);
                    }
                    else
                    {
                        members[key] = value;
                    }
                    return true;
              }

            public override bool TryGetMember(GetMemberBinder binder, out object result)
            {
                    if (members.ContainsKey(binder.Name))
                    {
                        result = members[binder.Name];
                        return true;
                    }

                    return base.TryGetMember(binder, out result);
              }

            public override IEnumerable<string> GetDynamicMemberNames()
            {
                return members.Keys;
            }
        }

Note that colAppendIndex is an incremental number which appends a number in front of the key of the property name. This gives us the uniqueness of the keys in the dictionary.
If you call this method in console app and binds to json as below


static void Main(string[] args)
           {
               var json = JsonConvert.SerializeObject(GenerateData(), Formatting.Indented); //using Newtonsoft.Json lib
               Console.WriteLine(json);
               Console.Read();
           }

Output:

{

  "Data": [

    {

      "Column1": "row1Col1",

      "Column2": "row1Col2",

      "Column3": "row1Col3"

    },

    {

      "Column1": "row2Col1",

      "Column2": "row2Col2",

      "Column3": "row2Col3"

    }

  ]

}