I have a struct:
public struct MyStruct
{
public readonly string Str1;
public readonly string Str2;
}
According to the Internet, you really should only use structs if their size is 16 bytes or less. If more, performance issues can happen. From various searches, a string stores 2 bytes per character. This means that if you have a string in a struct, it could only have 8 characters at most, assuming it's the only string in your struct. In my example, that'd be split among both fields I have.
Elsewhere, however, I've read that only the string reference is put in the struct, not the string itself.
My question is: Does the 16 byte recommendation/limitation of C# structs mean that I basically can't use strings in them. I like taking advantage of structs sometimes (especially the cannot-be-null parts of it), so I want to know if there's still a way to use them while following the recommendations.
EDIT: Poor choice of words on my part. Indeed it's not a limitation of the language, but rather a recommendation based on performance to not exceed 16 bytes in one's structs. I think I'm falling victim to premature optimization here: Perhaps I should only worry about this limitation if I see actual performance problems in my application, rather than fretting over small numbers of bytes.
One coloured line should be in the control line region (C), and another coloured line should be in the test line region (T). Two lines, one next to C and one next to T, even faint lines, show the test is positive.
This is what the test “window” looks like in the strip after 30 minutes. “C” stands for “control” – this is to make sure the test is working. “T” stands for “test” – this is where your sample result will appear. Image © https://www.gov.uk/ Negative result: one line next to C shows the test is negative.
For most positive tests, a reddish-purple line will appear in the Control (C) Zone and the Test (T) Zone; however, in cases where the viral load in the sample is very high, the line in the Control (C) Zone may not be present or may be very faint.
This indicates the test is negative. Two lines – even faint lines – indicate the test is positive. The test has failed and should be retaken. Negative result.
Advice regarding the 16-byte threshold should be considered out of date. The .NET Runtime optimizes operations on structures below a certain size (which used to be 16 bytes, but has since increased to I think 24); the cost per byte increases when structures exceed that size, but that doesn't mean one should use a class for everything larger than that.
The cost of creating a new structure is proportional to its size. The cost of creating a new class object is proportional to its size plus some significant additional overhead. The cost of copying an existing structure is proportional to its size, with a penalty for structs over a certain size. The cost of copying a reference to an immutable class object is fixed and small.
Creating a structure of any size and copying it once or twice will always be cheaper than creating a class object of the same size and copying the reference likewise. If the structure or class reference would get copied millions of times, even a 12-byte class might outperform a 12 byte structure. For values in between, the break-even size for class vs. structure will depend upon the number of times a struct or class reference would get copied, but unless a type is really big or would be copied many thousands of times, the extra cost to copy structures will still be cheaper than the extra cost to create class objects.
With regard to the fact that a structure contains strings, one should regard a reference to an immutable-type object as having a cost of 4 or 8 bytes on a 32-bit or 64-bit system. Since a string
field does not "hold" a string but merely identifies one, a struct with two string
fields would thus take 8 or 16 bytes, regardless of the lengths of the strings identified thereby.
String
is a reference type, so in this case, you are only holding 2 references to your two string
s however long they are. The 2 references, are 4 bytes each on a 32-bit system, and 8 byte each on a 64-bit system. They contain the memory address of your strings.
The guideline of this 16 byte struct limitation
is probably because when you are passing a struct (vs. a class), the values get copied. If the struct is large, then a lot of memory copying will be done, which will negatively impact the performance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With