Search code examples
c#classstructmonogame

Best way to pair a Pre-made Class and primitive type C#


Basically, I'm wanting to efficiently pair multiple bool and bytes ( to store values ) with a pre-made class (RenderTarget2D if you must know).

Obviously, I can wrap this all in a class, however there are situations when I will be having many of these, and would like to save on memory where possible (ie use a struct).

I know it's bad behaviour to use a struct with reference variables, and I'd prefer not to just use separate variables to hold the information ( would rather pair it all together ).

Essentially I am wanting a structure to hold a reference to a class, a bool, and a byte, and create a 2D array of this to make many (thus am looking for a mitigate memory usage)

Am I overlooking an obvious solution?


Solution

  • Understanding the question as:

    You want something that holds a bool, a byte and an instance of the class RenderTarget2D.

    If that is the case you can use Tuple<bool, byte, RenderTarget2d>.

    Creating a custom class or struct is also a viable option. In fact there is a proposal for "C# 7" to include language native tuples (that will not be System.Tuple) and as currently written, they will be structs.


    You may also want to consider that having a reference to the RenderTarget2d may prolong its lifespan.


    Struct vs Class

    The struct takes in memory (when compacted) the size of a bool plus the size of a byte plus the size of a reference (to RenderTarget2d). If you have an array of 600 by 600 (360000) of such structs it takes 360000 the size of the struct in memory.

    If you use classes, the array will have 360000 references to the actual location of the data that in total takes at least as much as the array of structs.

    So using the structs should take less memory...

    But when you take a struct from your data structure, you are actually making a copy. So each time you access your array to get a item and read a property of that item, you are actually making a copy of the item and reading the property from that copy.

    If you want to update it, you need to read it (that makes a copy as mentioned above) edit it, and then put it back... and that copies the data to the array.

    So, if the memory is the main concern. Use struct. To quote Jon Skeet: "so long as you're aware of the consequences".


    Using struct also means less RAM round trips. Not only because it avoids resolving the references, but also because the data is guaranteed to be close together. This allows for better performance because the CPU will load a chunk (or the totality) of the data structure in cache and since the code is not using references outside of that it will be able to keep it in cache instead of going to load another thing.