Есть 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).
Комментариев нет:
Отправить комментарий