Страницы

Поиск по вопросам

понедельник, 10 июня 2019 г.

Преймущества двойного указателя перед одним указателем в реализации класса matrix

Есть 2 реализации класса matrix на С++. Первый вариант с использованием указателя на массив элементов матрицы int *elems_. Для получения элемента матрицы в классе перегружен оператор ()
int& operator() (size_t n, size_t m) const { return this->elems[m * this->cols + n]; }
Второй вариант с использованием двойного указателя (двумерный массив). Выглядит это так int **elems_. Для получения элемента матрицы такая перегрузка оператора:
int& operator() (size_t n, size_t m) const { return this->elems[m][n]; }
Какие есть плюсы и минусы при обоих подходах?


Ответ

На мой взгляд, здесь самый существенный момент - работа с большими матрицами. Ибо в таком случае большое значение имеет работа процессорного кэша. И тогда есть 2 аспекта:
Как реализован сам класс. С этой точки зрения, первый способ лучше, так как он выделяет один непрерывный блок данных, а второй - множество блоков поменьше (и они не обязаны быть смежными). Как вы используете матрицу. Например, если вы последовательно обходите элементы матрицы построчно, то кэш используется эффективно. А если вы обращаетесь к случайным элементам матрицы, то будут частые промахи кэша, подкачка страниц, и все такое прочее. И тогда аспект 1 не имеет значения.
Кстати, совместить ваши способы можно таким образом:
Выделить память одним большим куском; Создать также массив, который будет содержать указатели на начала строк матрицы;
Тогда доступ к элементу можно будет делать как в способе 2, а данные при этом будут лежать в непрерывном блоке данных как в способе 1. При этом накладные расходы - дополнительный массив для указателей (что и так имеется в способе 2).

Комментариев нет:

Отправить комментарий