In general, use a type that makes sense. This can be useful in terms of validating data, integrity, and resilience.
Typically, for example, bool actually consumes 4 bytes in a 32-bit architecture, possibly 8 bytes in a 64-bit architecture due to filling and alignment problems. Most compilers optimize speed by default rather than code size or memory usage. Aligned access is usually faster than uneven access. In .Net, some of them can be controlled using attributes. As far as I know, the JIT compiler makes no effort to compact multiple boolean types into an integer bit field.
The same is true for byte types. The JIT compiler can combine several byte types (and even change the storage order) to share the same word (if you do not override this behavior with attributes such as FieldOffset and FieldOffset ).
For instance:
struct Foo { string A; short B; string C; short D; }
Considering reference types as pointers, the above is likely to have a size of 16 (maybe 14, but aligned to 16).
Foo can be rearranged so that the order is actually:
struct Foo { string A; string C; short B; short D; }
The above will probably have a size of 12 and an alignment of 12 or 16 (probably 16).
... perhaps in this contrived example you could save 4 bytes due to rearrangement. And note that .Net is more aggressive about redistributing elements than a regular C ++ compiler.
(Aside, I recently spent some effort in the C ++ library that I support. I was able to achieve a 55% reduction in memory usage, only by optimizing the member layout).
source share