В C есть разница во времени и пространстве между двумерным массивом m × n и 1-мерным массивом длины m × n (при больших значениях m и n)? Будет ли доступ к элементам быстрее с помощью одномерного массива?Производительность двухмерного массива по сравнению с одномерным массивом
ответ
В C двумерные массивы - это просто аккуратная схема индексирования для одномерных массивов. Так же, как с 1D-массивом, 2D-массивы выделяют один блок смежной памяти, а нотация A[row][col]
похожа на A[row*NCOLS+col]
.
Обычно, если вы должны были реализовать свои собственные многомерные массивы с использованием одномерных массивов, вы бы написать функцию индексирования:
int getIndex(int row, int col) { return row*NCOLS+col; }
Предполагая, что ваш компилятор встраивает эту функцию, производительность здесь будет точно таким же, как если вы использовали встроенную функцию индексирования 2D-массивов.
Для иллюстрации:
#define NROWS 10
#define NCOLS 20
Это:
int main(int argc, char *argv[]) {
int myArr[NROWS*NCOLS];
for (int i=0; i<NROWS; ++i) {
for (int j=0; j<NCOLS; ++j) {
myArr[getIndex(i,j)] = i+j;
}
}
return 0;
}
Если выполнять так же, как это:
int main(int argc, char *argv[]) {
int myArr[NROWS][NCOLS];
for (int i=0; i<NROWS; ++i) {
for (int j=0; j<NCOLS; ++j) {
myArr[i][j] = i+j;
}
}
return 0;
}
Хотя как AraKpointed out, если вы прыгали строк много , и строки очень большие, вы можете поразить множество ошибок страницы ... в этом случае cust Функция индексирования om (с переключением строк и столбцов) могла бы помочь, но так же может просто изменить, какие измерения в двумерном массиве вы рассматриваете как строки и которые вы рассматриваете как столбцы.
Я не думаю, что есть какая-то разница. Внутренне c обрабатывает двумерный массив, например, несколько одномерных массивов.
Однако, как и при всей производительности, ваш пробег может отличаться. Может быть какая-то тонкая арифметическая разница указателя. Запускайте тесты по времени в обоих сценариях. Какой бы ни побежал быстрее.
Не можете ли вы также реализовать массивы в C, например, 'int ** array', а затем вы будете массивом' array = malloc (sizeof (int *) *); for (i = 0; i
@derobert: Эта структура часто называется «оборванной решеткой». Он имеет аналогичный синтаксический доступ, но на самом деле это не то же самое, что обычный 2d-массив. – dmckee
@dmckee рваный или зубчатый? –
Я только догадываюсь, но я бы сказал, что 1-й массив быстрее, чем 2d-массив. Однако это было бы не намного быстрее. Вид как $ 1,000,000.01 составляет более $ 1,000,000.
Я бы использовал все, с чем проще кодировать.
На самом деле, если вы используете так называемый двумерный массив в C, компилятор выполнит преобразование в одномерный массив для вас. Если вы используете одномерный массив, и вам нравится относиться к нему как к двумерному, вы должны сами написать отображение.
Единственное, что вам нужно позаботиться, это получить доступ к массиву по-разному, потому что компилятор C сохранит вашу двумерную строку массива за строкой. Если вы получаете доступ к «большому» двумерному массиву по столбцу, тогда могут возникнуть ошибки страниц. Даже если вы программируете на языке, который поддерживает только одномерные массивы, вы можете легко записать отображение в любое количество измерений.
Посмотрите на эту статью в Википедии, если вы хотите сделать mapping row-wise. Ваше сопоставление может быть по столбцу, например, как матрицы FORTRAN.
Robert is correct.Выражения индексирования скомпилированы для арифметических выражений указателя, и поэтому нет никакой разницы.
Однако, это может повлиять на порядок доступа, поэтому вы можете сами реализовать вещи, чтобы вы могли контролировать порядок доступа. Например, первая строка первой и первой строки строки.
На современных процессорах доступ к большим массивам с различными шагами может иметь неожиданные отличия в производительности. Последовательный доступ всегда самый быстрый, а другие шаги могут быть в 30 раз медленнее из-за взаимодействия с кешем. Многомерные массивы, где внутренние размеры являются мощью двух, часто имеют низкую производительность из-за того, что они взаимодействуют с ассоциацией кеша. Чтобы понять эти проблемы, нет никакой реальной замены для измерения.
Вам не нужно писать самостоятельно, чтобы определить макет; макет встроенного C четко определен. Вы можете выбрать, что использовать, написав 'array [row] [column]' vs. 'array [column] [row]' – derobert
Да, это правда. Я должен был дать лучший пример, например различные схемы блокированных матриц. –
Как сказано другим, разница в том, как вы получаете доступ к своим товарам: что имеет значение, если ваши элементы являются макетом в памяти, который является линейным, по крайней мере, на общих архитектурах. Итак, все, что у вас на самом деле - это 1d-массив, 2d и т. Д. - это просто «удобство», а разумный компилятор должен оптимизировать индексирование, но на практике, когда у вас есть несколько переменных, компиляторы часто терпят неудачу на arch как x86 из-за голода регистрации.
Теперь это зависит от вашего приложения, но я думаю, вы должны подумать с 1d макетом по умолчанию, особенно если вам нужно обрабатывать несколько измерений. Первая проблема с многомерными массивами в C состоит в том, что вы не можете их динамически распределять - если вы распределяете по каждой строке, у вас будут ужасные характеристики, потому что у вас нет смежной части памяти. Подробнее об этом см. В разделе FFTW doc.
Обратите внимание, что вы всегда можете описать свою единую память с удобной индексацией массива поверх нее (вы выделяете один большой блок памяти nxm, а затем создаете массив из n указателя на каждую строку).
- 1. Сравнение двухмерного массива с одномерным массивом
- 2. Сравнение двухмерного массива с одномерным массивом в Java
- 3. Поиск двухмерного массива другим массивом
- 4. Заполните одну строку двумерного массива одномерным массивом
- 5. Возникли проблемы с одномерным массивом
- 6. Дерево подобная структура с одномерным массивом
- 7. d3: дублирующие пути с более одномерным массивом
- 8. Сортировка php-массива по значению по сравнению с другим массивом
- 9. объекта Java с переменным одномерным массивом
- 10. Ошибка запуска Newtonsoft.json: массив не был одномерным массивом
- 11. getchar() в трудности с одномерным массивом
- 12. Эффективность памяти: HashMap по сравнению с массивом
- 13. jQuery text() не по сравнению с массивом
- 14. Индексирование номеров с одномерным булевым массивом
- 15. Сортировка массива N-D numpy другим одномерным массивом
- 16. Perl: ссылка массива по сравнению с анонимным массивом
- 17. JavaScript Замените соответствующие элементы массива по сравнению с другим массивом
- 18. Сортировка по диагонали двухмерного массива
- 19. Сортировка двухмерного массива по дате
- 20. Производительность Selenium Webdriver по сравнению с временем
- 21. разница между массивом с нулевым по сравнению с нулевым массивом
- 22. Лучшая производительность по сравнению с String.Empty (с #)
- 23. производительность с PDO по сравнению с mysql
- 24. Выбор элементов хэша по сравнению с массивом
- 25. Сравнение строк по сравнению с байтовым массивом
- 26. проблема освобождения вектора по сравнению с массивом
- 27. Typeahead, который должен быть одномерным массивом
- 28. Создайте 2-мерный массив с 2 одномерным массивом
- 29. Проблема с добавлением двухмерного массива
- 30. Плохая производительность NServiceBus по сравнению с MSMQ
Отличное объяснение, спасибо! –