Представление 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-координату.