【问题标题】:Jagged array versus one big array?锯齿状阵列与一个大阵列?
【发布时间】:2013-04-15 12:35:28
【问题描述】:

不太清楚如何问这个问题,但我有 2 种方法(到目前为止)查找数组

选项1是:

bool[][][] myJaggegArray;

myJaggegArray = new bool[120][][];
for (int i = 0; i < 120; ++i)
{
  if ((i & 0x88) == 0)
  {
    //only 64 will be set
    myJaggegArray[i] = new bool[120][];
    for (int j = 0; j < 120; ++j)
    {
      if ((j & 0x88) == 0)
      {
        //only 64 will be set
        myJaggegArray[i][j] = new bool[60];
      }
    }
  }
}

选项2是:

bool[] myArray;
//                [998520]
myArray = new bool[(120 | (120 << 7) | (60 << 14))];

这两种方法都很好用,但是是否有另一种(更好的)方法来进行快速查找,如果速度/性能很重要,您会采用哪种方法?

这将用于chessboard implementation (0x88),主要是

[from][to][dataX] 用于选项 1

[(from | (to &lt;&lt; 7) | (dataX &lt;&lt; 14))] 用于选项 2

【问题讨论】:

  • 我会选择最容易使用和阅读的选项。当你的代码完成并且你觉得它应该比现在更快时,你总是可以稍后进行优化。
  • @Nolonar,其实我现在就到了
  • 我会使用一个带有所有三个参数的 getter 方法的大型数组。既快速又易读,并且允许将来进行简单的更改。
  • @Nolonar:这是国际象棋。您知道在编写第一行代码之前它还不够快。你总是需要更多的国际象棋表现。
  • 数字 0x88、120 和 60 的故事是什么?

标签: c# chess


【解决方案1】:

我建议使用一个大数组,因为拥有一个大内存块的优点,但我也鼓励为该数组编写一个特殊的访问器。

class MyCustomDataStore
{ 
  bool[] array;
  int sizex, sizey, sizez;

  MyCustomDataStore(int x, int y, int z) {
    array=new bool[x*y*z];
    this.sizex = x;
    this.sizey = y;
    this.sizez = z;
  }

  bool get(int px, int py, int pz) {
    // change the order in whatever way you iterate
    return  array [ px*sizex*sizey + py*sizey + pz ];
  }

}

【讨论】:

  • 它更容易阅读,但是通过查看 IL 代码(除非 jitter 进行内联),这不会被内联并且在大循环中花费很多。
  • 同意,除非内联函数调用可能会降低效率。也许标记get方法sealed可能会提高机会。
  • 快速说明,x*y*zpx*sizex*sizey + py*sizey + pz 是错误的,两者都应该是 (x | (y &lt;&lt; 7) | (z &lt;&lt; 14)),而不是将它们保存在局部变量中。
【解决方案2】:

我只是用 z-size

edit2:更新为'

class MyCustomDataStore
{
     long[] array;

     MyCustomDataStore() 
     {
          array = new long[128 | 128 << 7];
     }

     bool get(int px, int py, int pz) 
     {
          return (array[px | (py << 7)] & (1 << pz)) == 0;
     }

     void set(int px, int py, int pz, bool val) 
     {
          long mask = (1 << pz);
          int index = px | (py << 7);
          if (val)
          {
               array[index] |= mask;
          }
          else
          {
               array[index] &= ~mask;
          }
     }
}

编辑:性能测试: 使用 100 次 128x128x64 填充和读取

long: 9885ms, 132096B
bool: 9740ms, 1065088B

【讨论】:

  • 今晚我一定会试试这个
  • 像我对 dariusz 的解决方案所说的快速注释,执行 120*120*60 然后使用相同的方法读取值对于我所说的是错误的,它应该基于(x | (y &lt;&lt; 7) | (z &lt;&lt; 14))
  • 我刚试过,它让一切都比 bool 数组慢了一点
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-30
  • 2016-07-09
  • 2021-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-04
相关资源
最近更新 更多