2013-04-15 2 views
8

Не так уверен, как задать этот вопрос, но у меня есть 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 << 7) | (dataX << 14))] для варианта 2

+3

Я бы выбрал вариант, который проще всего использовать и читать. Вы можете всегда оптимизировать позже, когда ваш код закончен, и вы чувствуете, что он должен быть быстрее, чем он есть. – Nolonar

+0

@Nolonar, на самом деле, я сейчас нахожусь – Fredou

+0

Я бы использовал один большой массив WITH с методом геттера со всеми тремя параметрами. Быстро, легко читается и допускает простые будущие изменения. – Dariusz

ответ

2

Я предложил бы использовать один большой массив, из-за преимущества, имеющие один большой блок памяти, но я также рекомендовал бы написать специальный аксессор к этому массиву.

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 ]; 
    } 

} 
+0

его легче читать, но, посмотрев на код IL (если только джиттер не делает вставку), это не становится вложенным и дорого стоит, находясь в большой петле. – Fredou

+0

Согласовано, если не указано, вызов функции может сделать его намного менее эффективным. Возможно, маркировка метода get «запечатанная» может улучшить вероятность. – Dariusz

+0

quick note, 'x * y * z' и' px * sizex * sizey + py * sizey + pz' неверно, это должно быть '(x | (y << 7) | (z << 14))' для обоих без сохранения их в локальной переменной. – Fredou

1

Я просто обновить решение Дариуш с множеством длинных позиций для г размер < = 64

edit2 обновлен до '< <' версии, размер прикрепленного к 128x128x64

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 
+0

Я окончательно попробую сегодня вечером – Fredou

+0

быструю заметку, как я сказал для решения dariusz, делая 120 * 120 * 60, а затем, используя то же самое, чтобы прочитать значение, неверно для того, что я сказал, оно должно основываться на '(x | (y << 7) | (z << 14)) ' – Fredou

+0

Я просто попробовал, и он сделал все немного медленнее, чем массив bool – Fredou

Смежные вопросы