Search code examples
c#structmemory-managementclass-design

Why is 16 byte the recommended size for struct in C#?


I read the Cwalina book (recommendations on development and design of .NET applications).

He says that a good designed struct has to be less than 16 bytes in size (for performance purposes).

Why exactly is this?

And (more important) can I have larger struct with same efficiency if I run my .NET 3.5 (soon to be .NET 4.0) 64-bit application on Core i7 under Windows 7 x64 (is this limitation CPU / OS based)?

Just to stress again - I need as efficient struct as it is possible. I try to keep it on the stack all the time. The application is heavily multi-threaded and runs on sub-millisecond intervals, and the current size of the struct is 64 bytes.


Solution

  • Only you know how your structs are being used in your program. But if nothing else, you can always test it for yourself. For instance, if it's frequently passed to other functions, the following may illuminate you:

    class MainClass
    {
        static void Main()
        {
            Struct64 s1 = new Struct64();
            Class64 c1 = new Class64();
            DoStuff(s1);
            DoStuff(c1);
            Stopwatch sw = new Stopwatch();
            sw.Start();
            for (int i = 0; i < 10000; i++)
            {
                s1 = DoStuff(s1);
            }
            sw.Stop();
            Console.WriteLine("Struct {0}", sw.ElapsedTicks);
            sw.Reset();
    
            sw.Start();
            for (int i = 0; i < 10000; i++)
            {
                c1 = DoStuff(c1);
            }
            sw.Stop();
            Console.WriteLine("Class {0}", sw.ElapsedTicks);
            sw.Reset();
    
            Console.ReadLine();
        }
    }
    

    with:

    public class Class64
    {
        public long l1;
        public long l2;
        public long l3;
        public long l4;
        public long l5;
        public long l6;
        public long l7;
        public long l8;
    }
    public struct Struct64
    {
        public long l1;
        public long l2;
        public long l3;
        public long l4;
        public long l5;
        public long l6;
        public long l7;
        public long l8;
    }
    

    Try this sort of thing with representative structs/classes, and see what results you get. (On my machine, above test, the class seems ~3 times faster)