Это инициализация 2D массива плохая идея? - PullRequest
1 голос
/ 16 мая 2010

У меня есть кое-что, для чего мне нужен 2D-массив, но для лучшей производительности кэша я бы предпочел, чтобы это был обычный массив. Вот идея, которая у меня была, но я не знаю, ужасная ли это идея:

const int XWIDTH = 10, YWIDTH = 10;
int main(){
    int * tempInts = new int[XWIDTH * YWIDTH];
    int ** ints = new int*[XWIDTH];
    for(int i=0; i<XWIDTH; i++){
        ints[i] = &tempInts[i*YWIDTH];
    }
    // do things with ints
    delete[] ints[0];
    delete[] ints;
    return 0;
}

Таким образом, идея состоит в том, что вместо new набора кучек массивов (и размещения их в разных местах в памяти) я просто указываю на массив, который я создал все сразу.

Причина delete[] (int*) ints; заключается в том, что я на самом деле делаю это в классе, и это сэкономит [тривиальные объемы] памяти, чтобы не сохранить исходный указатель.

Просто интересно, есть ли причины, это ужасная идея. Или, если есть более простой / лучший способ. Цель состоит в том, чтобы иметь доступ к массиву как ints[x][y], а не ints[x*YWIDTH+y].

РЕДАКТИРОВАТЬ: простой тест предполагает, что мой путь быстрее без оптимизатора, но gcc может по какой-то причине лучше оптимизировать простой способ.

http://pastebin.com/YDRuLuXv

Если вы компилируете с помощью gcc -O0, лучшим должен быть стек, затем мой, а затем обычный. Если вы компилируете с X_MAX, установленным на большое значение, и Y_MAX, установленным на небольшое значение, и используете gcc -O3, мой и стек должны быть действительно очень быстрыми, но нормального не будет. Если вы сделаете X_MAX маленьким, а Y_MAX большим, нормальный способ должен победить (даже по некоторым причинам над стековым методом).

Ответы [ 3 ]

2 голосов
/ 16 мая 2010

Проблема такого подхода в том, что он подвержен ошибкам. Я бы посоветовал вам обернуть распределение и доступ к отдельным элементам вашего 2D-массива в классе.

class Array2D
{
private:
    /* Pointer necessary for the choosen implementation */
public:
    Array2D(unsigned int dim1, unsigned int dim2);
    ~Array2D() /* Needed, since you will be allocation memory for this class */
    double operator()(unsigned int x, unsigned int y);
}

В этом случае, если вам когда-нибудь понадобится изменить распределение, вы можете только изменить реализацию методов, оставив интерфейс без изменений. Остальная часть вашего кода будет фактически использовать только operator () и конструктор. Это также поможет вам предотвратить утечку памяти.

1 голос
/ 16 мая 2010

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

Если вам нужен 2D-массив, просто объявите его и используйте. Сокращение количества ошибок и технического обслуживания будет гораздо выгоднее, чем любое повышение производительности, которое может вообще не существовать.

0 голосов
/ 21 мая 2010

Я нашел лучший способ. В Boost есть библиотека для многомерных массивов: boost::multi_array.

Получил идею от этого вопроса .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...