Представление 2D-массива в виде массива 1D [дубликат]

Возможные Дубликаты:
реализация матрицы, которая более эффективна-с использованием массива массивов (2D) или массива 1D?
производительность 2-мерного массива против 1-мерного массива

на днях я смотрел на одну из кодовых баз молекулярной динамики моего приятеля, и он представил некоторые 2D-данные в виде массива 1D. Поэтому вместо того, чтобы использовать два индекса, он должен отслеживать только один, но немного математики делается, чтобы выяснить, в каком положении он был бы, если бы он был 2D. Итак, в случае этого 2D-массива:

two_D = [[0, 1, 2],
         [3, 4, 5]]

это будет представлено как:

one_D = [0, 1, 2, 3, 4, 5]

Если бы ему нужно было знать, что находится в позиции (1,1) 2D-массива, он сделал бы простую алгебру и получил 4.

есть ли повышение производительности, полученное с помощью массива 1D, а не 2D-массива. Данные в массивах можно вызывать миллионы раз во время вычисление.

Я надеюсь, что объяснение структуры данных-это понятно...если не дайте мне знать, и я постараюсь объяснить это лучше.

спасибо :)

редактировать Язык-C

5 ответов



для 2-d массива ширины W и высоты H вы можете представить его как 1-d массив длины W * H, где каждый индекс

 (x,y)

где x-столбец, а y-строка, 2-d массива сопоставляется с индексом

i=y*W + x

в 1-D массиве. Аналогично вы можете использовать обратное отображение:

y = i / W
x = i % W

. Если вы сделаете W мощностью 2 (W=2^m), вы можете использовать hack

y = i >> m;
x = (i & (W-1))

где эта оптимизация ограничена только случаем, когда W является a мощность 2. Компилятор, скорее всего, пропустит эту микро-оптимизацию, поэтому вам придется реализовать ее самостоятельно.

модуль является медленным оператором в C / C++, поэтому его исчезновение выгодно.

кроме того, с большими 2-d массивами имейте в виду, что компьютер хранит их в памяти как 1-d массив и в основном вычисляет индексы, используя сопоставления, перечисленные выше.

гораздо важнее, чем способ определения этих сопоставлений, является то, как массив доступный. Есть два способа сделать это: столбец major и строка major. Путь, который вы проходите более важно чем любой другой фактор, потому что он определяет, если вы используете кэширование в свою пользу. Пожалуйста, прочитайте http://en.wikipedia.org/wiki/Row-major_order .


часто 2D-массивы реализуются как 1D-массивы. Иногда 2D-массивы реализуются 1D-массивом указателей на 1D-массивы. Первый случай, очевидно, не имеет штрафа за производительность по сравнению с массивом 1D, потому что он идентичен массиву 1D. Второй случай может иметь небольшое снижение производительности из-за дополнительной косвенности (и дополнительных тонких эффектов, таких как уменьшенная локальность кэша).

Он отличается для каждой системы, какой вид используется, поэтому без информации о том, что вы используете, что нет никакого способа быть уверенным. Я бы посоветовал просто проверить производительность, если это действительно важно для вас. И если производительность не так важна, тогда не беспокойтесь об этом.

для C 2D-массивы являются массивами 1D с синтаксическим сахаром, поэтому производительность идентична.


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

на других языках 2d-массив может быть массивом указателей на внутренние массивы, и в этом случае доступ к элементу будет Array lookup + pointer dereference + array поиск, который, вероятно, медленнее, чем арифметика индекса, хотя не стоит оптимизировать, если вы не знаете, что это узкое место.


oneD_index = 3 * y + x;

где x-позиция в строке, а y-позиция в столбце. Вместо 3 вы используете ширину столбца. Таким образом, вы можете преобразовать 2D-координаты в 1D-координату.