2
\$\begingroup\$

I have a structure, and have come up with 3 different 3D arrays to store it in. The thing is, optimization is not my specialty and I need advice from someone who knows their stuff regarding best ways to store and access multi dimensional arrays of structures. I need to know if any of these methods are better in terms of memory use, or speed of access, etc. when compared to each other.

Is there an even better way to store and access the structure aside from arrays that I am not aware of? I mainly used this and other Stack Overflow posts for reference.

I'm aware that performance and memory use is probably negligible when it comes to small data sets, but the reason I am posting here is because I know that eventually whatever method I choose will be used for very large data sets, and I want to avoid a potential problem down the road.

Currently, I am planning to use one of the methods for a 5 by 8 by X array. I initialized each of the methods below to be 2 by 2 by X, to make it easier to see where items are added.

The three methods are as follows:

Class array nesting - array of items stored in a class that is an array inside another class.

public static Tier3[] _Tier3 = new Tier3[2]

3D full jagged array - an array that is expandable in all three dimensions.

public static Item[][][] _3DjaggedItems = new Item[2][][]

2D rectangular array - a 2D array set in 2 dimensions storing jagged arrays.

public static Item[,][] _2Drectangle_3DjaggedItems = new Item[2,2][]

If you know a better method of storing and accessing this struct, please keep in mind that you must be able to print out "Hello, world!" by assigning values to

public ItemSystem.Item _Item;
public ItemSystem.Item[] _ItemList;

and calling PrintTest() to print the message.

Here is the test code I wrote using all three methods to print out "Hello, world!". Just copy paste into C# compiler of choice to run. I used http://rextester.com/.

//Rextester.Program.Main is the entry point for your code. Don't change it.
//Compiler version 4.0.30319.17929 for Microsoft (R) .NET Framework 4.5

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace Rextester
{
public class ItemSystem
{
    public struct Item
    {
        public string _1;
        public string _2;
        public string _3;
    }

    public class Tier2
    {
        public Item[] _Items;
    }

    public class Tier3
    {
        public Tier2[] _Tier2;
    }

    //The class of containers the data of which is initialized once.
    public static Tier3[] _Tier3 = new Tier3[2]
    {
        new Tier3()
        {
            _Tier2 = new Tier2[2]
            {
                new Tier2()
                {
                    _Items = new ItemSystem.Item[]
                    {
                        new Item() { _1 = "H", _2 = "e", _3 = "l" },
                        new Item() { _1 = "l", _2 = "o", _3 = "," },
                        new Item() { _1 = " ", _2 = "w", _3 = "o" },
                        new Item() { _1 = "r", _2 = "l", _3 = "d" },
                        new Item() { _1 = "!", _2 = "", _3 = ""   }
                    }
                },
                new Tier2()
                {
                    _Items = new ItemSystem.Item[]
                    {
                        new Item() { _1 = "H", _2 = "e", _3 = "l" }
                    }
                },
            }
        },
        new Tier3()
        {
            _Tier2 = new Tier2[2]
            {
                new Tier2()
                {
                    _Items = new ItemSystem.Item[]
                    {
                        new Item() { _1 = "H", _2 = "e", _3 = "l" }
                    }
                },
                new Tier2()
                {
                    _Items = new ItemSystem.Item[]
                    {
                        new Item() { _1 = "H", _2 = "e", _3 = "l" }
                    }
                },
            }
        },
    };

    public static Item[][][] _3DjaggedItems = new Item[2][][]
    {
        new Item[2][]
        {
            new Item[]
            {
                new Item() { _1 = "H", _2 = "e", _3 = "l" },
                new Item() { _1 = "l", _2 = "o", _3 = "," },
                new Item() { _1 = " ", _2 = "w", _3 = "o" },
                new Item() { _1 = "r", _2 = "l", _3 = "d" },
                new Item() { _1 = "!", _2 = "", _3 = ""   }
            },
            new Item[]
            {
                new Item() { _1 = "H", _2 = "e", _3 = "l" }
            },
        },
        new Item[2][]
        {
            new Item[]
            {
                new Item() { _1 = "H", _2 = "e", _3 = "l" }
            },
            new Item[]
            {
                new Item() { _1 = "H", _2 = "e", _3 = "l" }
            },
        },
    };

    public static Item[,][] _2Drectangle_3DjaggedItems = new Item[2,2][]
    {
        {
            new Item[]
            {
                new Item() { _1 = "H", _2 = "e", _3 = "l" },
                new Item() { _1 = "l", _2 = "o", _3 = "," },
                new Item() { _1 = " ", _2 = "w", _3 = "o" },
                new Item() { _1 = "r", _2 = "l", _3 = "d" },
                new Item() { _1 = "!", _2 = "", _3 = ""   }
            },
            new Item[]
            {
                new Item() { _1 = "H", _2 = "e", _3 = "l" },
            },
        },
        {
            new Item[]
            {
                new Item() { _1 = "H", _2 = "e", _3 = "l" },
            },
            new Item[]
            {
                new Item() { _1 = "H", _2 = "e", _3 = "l" },
            },
        },
    };
}

public class Program
{
    public ItemSystem.Item _Item;
    public ItemSystem.Item[] _ItemList;
    public int _Tier3Accessor = 0;
    public int _Tier2Accessor = 0;
    public void TestFunc()
    {
        _Item     = ItemSystem._Tier3[_Tier3Accessor]._Tier2[_Tier2Accessor]._Items[0];
        _ItemList = ItemSystem._Tier3[_Tier3Accessor]._Tier2[_Tier2Accessor]._Items;

        PrintTest();

        _Item     = ItemSystem._3DjaggedItems[_Tier3Accessor][_Tier2Accessor][0];
        _ItemList = ItemSystem._3DjaggedItems[_Tier3Accessor][_Tier2Accessor];

        PrintTest();

        _Item     = ItemSystem._2Drectangle_3DjaggedItems[_Tier3Accessor, _Tier2Accessor][0];
        _ItemList = ItemSystem._2Drectangle_3DjaggedItems[_Tier3Accessor, _Tier2Accessor];

        PrintTest();
    }

    public void PrintTest()
    {
        for(int i = 0; i < _ItemList.Length; i++)
        {
            Console.Write(_ItemList[i]._1);
            Console.Write(_ItemList[i]._2);
            Console.Write(_ItemList[i]._3);
        }

        Console.WriteLine("\n");
    }

    public static void Main(string[] args)
    {
        Program p = new Program();
        p.TestFunc();
    }
}
}
\$\endgroup\$
3
  • 4
    \$\begingroup\$ What's with the underscore? It's everywhere. Why would you do that? \$\endgroup\$
    – t3chb0t
    Jan 15, 2017 at 19:24
  • 1
    \$\begingroup\$ The naming convention _1 is making my eyes watery \$\endgroup\$
    – Tolani
    Jan 15, 2017 at 22:24
  • \$\begingroup\$ I'd like to give some contructive criticism to the actual performance of the algorithm. Whenever you're working with multidimensional arrays, try to flatten them. You can always access specific array elements using simple math, which could give you some extra performance. I.e. try to use Item[x*y*z] instead of Item[x][y][z], and instead use some processing power to calculate the array indices. \$\endgroup\$
    – maxb
    Jan 22, 2017 at 2:26

1 Answer 1

0
\$\begingroup\$

Figured it out. Did some more searching, and after a while came across these posts

https://stackoverflow.com/questions/597720/what-are-the-differences-between-a-multidimensional-array-and-an-array-of-arrays

https://stackoverflow.com/questions/468832/why-are-multi-dimensional-arrays-in-net-slower-than-normal-arrays

The short answer is that flattening arrays and then calculating the index you want to access is the fastest way to go. Followed by Jagged arrays, because the Multi Dimensional arrays have a slow implementation in C#.

In terms of formatting, Jagged arrays also allow you to keep a bit more organised due to how they need to be initialized. You could do the same with a flattened array, but you would need to get creative with spacing and commenting to make sure everything is where it should be visually for easy reading.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.