Why should a struct have a maximum of 16 bytes?

Asked

Viewed 122 times

8

I saw in a question about classes and structures that the latter should have a maximum of 16 bytes.

Why do you have this limitation?

1 answer

8


In fact you can use the size you want, the recommendation exists for efficiency. This recommendation is only to alert you to investigate further whether it will be a good option if you run away from any such item.

I don’t know if read here or elsewhere. Ali says that the struct is always a type by value, so an instance of it is the object itself. Whenever you copy its value you have to copy the object, if it is too large it is not very efficient. A type by reference has the object in the heap and what is copied is only the pointer, at most 8 bytes.

If you’re wondering if there’s too much copy, there is yes, every time you assign the value there is copy, if you pass it as argument there is copy, until the use there is copy to the register and possibly to the stack. Of course the copy to register or local (stack) is very fast. If the object already exists, the heap can be more or less fast too. But there is cost.

But I have already done tests and seen that in certain architectures this limit can be exceeded. If the cache line the processor’s higher performance for copying 1, 4, 16 or 64 bytes is virtually the same, if carrying 128 bytes will certainly consume at least twice the time of 64 bytes (probably more to manage complexity), at least on most current architectures. A lot of architectures nowadays use cache line 64-byte, so all internal physical bits transport takes place in 512-byte blocks. Transferring 1 or 64 bytes gives in it. There will be a difference to accommodate this data.

Of course, if architecture doesn’t have this kind of optimization, it can make a big difference. It may be that up to 16 bytes is too much, although the difference will not be too big. 16 bytes usually go well on all architectures and is sufficient for objects by value. If you use more than that maybe you’re doing something that should no longer be worth it.

In addition there may be some compiler optimization or Jitter that helps certain sizes. It’s good to keep in mind that this is implementation detail and it may be that in the past 16 bytes was the recommended one, but now it’s more. I have read that the trigger to change the generated code is 24 or 32 bytes in 64 bits. I have never found official information. I don’t know details but I’m likely to use more modern instructions (SSE) which allows single block copying. If you do not use such an instruction the copy should occur in steps, which will slow down.

If you need extreme optimization, if you want to avoid pressure on Garbage Collector it is possible to abuse a little of this type. This site uses it a lot in its architecture. You have to know what you’re doing because there’s a different semantics in being by value or reference, especially if the object is mutable.

In cases of abuse a little can avoid copying with ref, then the object is referenced and not copied, as if it were a type by reference. Then the copy will be at most 8 bytes. It is not always possible to use this type of artificial. But in C# 7 this has improved a lot because in addition to parameters it is possible to return a ref and use in local variables. And there is proposal to use ref in fields of an object, capture of Amble, etc..

Anyway it’s good not to abuse, and not to do premature optimization. You have to observe where and how that object will be used, in addition to the number of instances there will be.

My experience is that the biggest problem are the medium-life objects (objects that arrive in Gen1 mainly 2 and die then), although some too short-lived is a waste to be allocated in the heap.

If you know what you’re doing struct hundreds or thousands of bytes may be a good idea, although rare.

I will see if I make a test demonstrating this as soon as I have more time today. You have to take care not to fall into a trap. Today I think it comes out :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.