Home > Back-end >  Why is it wrong to serialize a struct?
Why is it wrong to serialize a struct?

Time:10-27

In a recent project of mine, I am using some struct, the reason I did so is because I am reading from a shared memory 'stream'.

It is not really possible to post the whole code, but I can basically summarize what I am doing:

 [StructLayout(LayoutKind.Sequential, Pack = 1)]

Reading from the memory stream and packing is working just fine, but then I serialize it to send over UDP or Websocket, and I am just sending double values, so I create another temporary struct to put the data I actually want to send, and populate it:

    public struct GPUInfo
    {
        public double TotalWatts { get; set; }
        public double Voltage { get; set; }
        public double CoreUsage { get; set; }
        public double MemUsage { get; set; }
    }
GPUInfo DUMMYDATA = new GPUInfo();
DUMMYDATA.TotalWatts = 20;
DUMMYDATA.Voltage = 1;
DUMMYDATA.CoreUsage = 100;
DUMMYDATA.MemUsage = 40;


byte[] BYTE = MessagePack.MessagePackSerializer.Serialize(DATA);

WS.Send(BYTE);

I am pretty sure that I am doing the correct thing using a struct as the 'base unpacking dictionary' for the shared memory stream, I am using Marshal.PtrToStructure. There's no doubt in my mind that this is correct, but I want to serialize some of the data previously collected, should I create a new class instead of a new struct? What is the difference?

Most online resources state that we should not serialize structs. What type of Serialization are they talking about?

DO NOT USE STRUCT

From Microsoft: CLASSES ARE BETTER

What do they mean by being boxed frequently?

structs are faster it seems, but I am still trying to grasp the meaning of serialization in this context, if I create a class without methods isn't it an anti pattern? I could be using a Dictionary and then throwing it away, will it be faster than struct?

STRUCTS ARE FASTER

Please understand, this question is not about Reading Shared Memory and using a struct to Marshall it, I don't know about any other method to do so. The question is: why is it wrong to Serialize a struct but not a class.

I'm happy serializing my structs, but it might be wrong and I want to know why. I could use a class, but a class without methods is an anti-pattern? (I hear it a lot on Stackoverflow).

Reference 1 (seems like it is common sense not to serialize struct): https://github.com/BenjaminAbt/SustainableCode/tree/main/csharp/struct-vs-class

Reference 2 (smaller than 16 bytes, and not boxed frequently): https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/choosing-between-class-and-struct

Reference 3 (classes without methods are an anti pattern): https://softwareengineering.stackexchange.com/questions/160675/what-do-you-call-classes-without-methods

I don't need methods. I could also create a Dictionary and throw it away, but I want to know the reason I have to do so, so I won't repeat this mistake on the future.

CodePudding user response:

Ok, this is an interesting topic, and I won't claim to be expert on it. I'll just respond with what I know.

Structs are often allocated on the stack memory. This is what makes them faster in overall terms. This increased speed is what makes game developers to use them so often.

Strictly speaking, it is not always the stack, but I won't enter into a deep discussion. Quickly searching I found this answer that describes in more detail how this goes.

So yes, your preference for serialization of a struct due to its increased performance is justified.

Because oftentimes structs are allocated in the stack, and the stack is much more limited than the heap, it is recommended that your structs be small or you'll hit memory exceptions fast. You must be mindful of your stack consumption. Another reason for the 16-byte limit is probably atomic operations. Anything larger cannot be atomically handled.

And finally, for your grand million dollar question: Is it wrong to serialize a struct? Ha! I don't have a definitive answer, but I'll venture say it is more of a warning, again, due to the risk of consuming stack memory in large quantities.

  • Related