多维数组与一维数组

Zet*_*Two 11 c# arrays performance multidimensional-array

这基本上是对这个问题的重述:Java:多维数组与一维数,但对于C#.

我有一定数量的元素可以作为网格存储.我应该使用数组[x*y]还是数组[x] [y]?

编辑:哦,所以有一维数组[x*y],多维数组[x,y]和锯齿状数组[x] [y],我可能想要锯齿状?

Bra*_*AGr 11

我对不合理的大型阵列进行了测试,并惊讶地看到Jagged数组([y] [x])似乎比单个维数阵列更快,手动乘法[y*ySize + x].并且多维数组[,]比较慢但不是那么多.

当然你必须测试你的特定阵列,但看起来差异并不大,所以你应该只使用适合你所做的最好的方法.

0.280 (100.0% | 0.0%) 'Jagged array 5,059x5,059 - 25,593,481'
|       0.006 (2.1% | 2.1%) 'Allocate'
|       0.274 (97.9% | 97.9%) 'Access'


0.336 (100.0% | 0.0%) 'TwoDim array 5,059x5,059 - 25,593,481'
|       0.000 (0.0% | 0.0%) 'Allocate'
|       0.336 (99.9% | 99.9%) 'Access'


0.286 (100.0% | 0.0%) 'SingleDim array 5,059x5,059 - 25,593,481'
|       0.000 (0.1% | 0.1%) 'Allocate'
|       0.286 (99.9% | 99.9%) 'Access'



0.552 (100.0% | 0.0%) 'Jagged array 7,155x7,155 - 51,194,025'
|       0.009 (1.6% | 1.6%) 'Allocate'
|       0.543 (98.4% | 98.4%) 'Access'


0.676 (100.0% | 0.0%) 'TwoDim array 7,155x7,155 - 51,194,025'
|       0.000 (0.0% | 0.0%) 'Allocate'
|       0.676 (100.0% | 100.0%) 'Access'


0.571 (100.0% | 0.0%) 'SingleDim array 7,155x7,155 - 51,194,025'
|       0.000 (0.1% | 0.1%) 'Allocate'
|       0.571 (99.9% | 99.9%) 'Access'



for (int i = 6400000; i < 100000000; i *= 2)
{
    int size = (int)Math.Sqrt(i);
    int totalSize = size * size;

    GC.Collect();

    ProfileTimer.Push(string.Format("Jagged array {0:N0}x{0:N0} - {1:N0}", size, totalSize));

    ProfileTimer.Push("Allocate");

    double[][] Jagged = new double[size][];
    for (int x = 0; x < size; x++)
    {
        Jagged[x] = new double[size];
    }

    ProfileTimer.PopPush("Allocate", "Access");

    double total = 0;
    for (int trials = 0; trials < 10; trials++)
    {
        for (int y = 0; y < size; y++)
        {
            for (int x = 0; x < size; x++)
            {
                total += Jagged[y][x];
            }
        }
    }

    ProfileTimer.Pop("Access");
    ProfileTimer.Pop("Jagged array");


    GC.Collect();

    ProfileTimer.Push(string.Format("TwoDim array {0:N0}x{0:N0} - {1:N0}", size, totalSize));

    ProfileTimer.Push("Allocate");

    double[,] TwoDim = new double[size,size];

    ProfileTimer.PopPush("Allocate", "Access");

    total = 0;
    for (int trials = 0; trials < 10; trials++)
    {
        for (int y = 0; y < size; y++)
        {
            for (int x = 0; x < size; x++)
            {
                total += TwoDim[y, x];
            }
        }
    }

    ProfileTimer.Pop("Access");
    ProfileTimer.Pop("TwoDim array");


    GC.Collect();

    ProfileTimer.Push(string.Format("SingleDim array {0:N0}x{0:N0} - {1:N0}", size, totalSize));

    ProfileTimer.Push("Allocate");

    double[] Single = new double[size * size];

    ProfileTimer.PopPush("Allocate", "Access");

    total = 0;
    for (int trials = 0; trials < 10; trials++)
    {
        for (int y = 0; y < size; y++)
        {
            int yOffset = y * size;
            for (int x = 0; x < size; x++)
            {
                total += Single[yOffset + x];
            }
        }
    }

    ProfileTimer.Pop("Access");
    ProfileTimer.Pop("SingleDim array");
}
Run Code Online (Sandbox Code Playgroud)


Ree*_*sey 10

C#在使用锯齿状数组(array[][])方面有许多优点.它们实际上通常会胜过多维数组.

话虽这么说,我个人会使用多维或锯齿状数组而不是单维数组,因为这会更紧密地匹配问题空间.使用一维数组会增加实现的复杂性,但这并不能提供真正的好处,特别是与2D数组相比,内部时,它仍然只是一块内存.

  • 对不起,我讨厌"Jagged Arrays"这个词..net文档抛出了很多术语,有人会认为锯齿状数组是一种新的数据类型.它只是一个阵列dangit! (4认同)
  • @JonH:是的,但这是官方术语,CLR中有一些特定的优化可以与他们合作. (3认同)

Sno*_*ear 9

优点array[x,y]:
- 运行时将为您执行更多检查.将检查每个索引访问是否在允许的范围内.使用另一种方法,您可以轻松地执行smth,例如a[y*numOfColumns + x]x可以超过"列数",并且此代码将提取一些错误的值而不会抛出异常.
- 更清晰的索引访问.a[x,y]比...更干净a[y*numOfColumns + x]

优点array[x*y]:
- 更容易迭代整个阵列.您只需要一个循环而不是两个循环.

赢家是...我更喜欢array[x,y]