Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NET] Why is struct better with being less than 16 bytes

Tags:

.net

I'm studying .NET structs - some books advise creating structs if they have an instance size less than 16 bytes.

Why is that?

like image 733
Ricky Avatar asked Mar 13 '10 10:03

Ricky


People also ask

How big should a struct be C#?

From what I've read, a struct should only be used if it's 16 bytes or less; otherwise it should be a class.

How many bytes does a struct use?

Above is the alignment of the structure A, and that's why the size of the struct is 32 Bytes. Also, the object a of type struct A is 32 Bytes.

Why is struct faster than class?

So based on the above theory we can say that Struct is faster than Class because: To store class, Apple first finds memory in Heap, then maintain the extra field for RETAIN count. Also, store reference of Heap into Stack. So when it comes to access part, it has to process stack and heap.

When should I use struct instead of class?

Class instances each have an identity and are passed by reference, while structs are handled and mutated as values. Basically, if we want all of the changes that are made to a given object to be applied the same instance, then we should use a class — otherwise a struct will most likely be a more appropriate choice.


2 Answers

It's because 16 bytes is the threshold where the compiler starts copying structs as block of memory instead of using one or two simple move instructions.

The compiler optimises the copying of structures when they are small. A struct that is for example eight bytes can be copied as a single 64 bit value. A struct that is 16 bytes can be copies as one or two singular values (depending on the processor architecture). When the structure is larger than 16 bytes, the compiler doesn't try to optimise the move any more, and the fallback is to call a method that copies a block of memory.

(Note: the threshold of 16 bytes may differ depending on the version of compiler, it seems as it actually tries to optimise beyond that point in newer versions, but the optimised code will still be a lot of move instructions, compared to copying a reference to an object which still is a single move operation.)

Edit:
Here is the result of a test that I did on my 64 bit system copying structs half a billion times:

struct 4    : 272 ms.
struct 8    : 235 ms.
struct 16   : 317 ms.
struct 32   : 625 ms.
struct 64   : 1280 ms.
struct 128  : 4659 ms.
struct 256  : 8020 ms.

As you see, below 16 bytes the time is not linear, although 16 bytes is four times as much as 4 bytes, it doesn't take four times longer. Above 16 bytes the time is linear, so doubling the size double the time. That's where it would start using multiple moves. Above 64 bytes there is a jump, where the time suddenly quadruples when the size doubles. That's where the fallback would start to be used.

like image 163
Guffa Avatar answered Oct 07 '22 21:10

Guffa


It's not exactly 16 bytes, but because structs are passed by value (copied whenever you give them to a method, assign them, etc.) they must not be too large. If they are, passing stuff by reference is cheaper.

4 years later: I answered this knowing very little about .NET (still don't know much about it). Guffa's answer is obviously more correct when dealing with "more or less than 16 bytes?", since at that size a bit of copying shouldn't matter much. My answer may be something to keep in mind when building huge structs.

like image 38
Bart van Heukelom Avatar answered Oct 07 '22 20:10

Bart van Heukelom