Когда производительность важна для приложения, следует ли учитывать, следует ли объявлять массив в стеке против кучи? Позвольте мне изложить, почему этот вопрос пришел на ум.
Поскольку массивы в C/С++ не являются объектами и распадаются на указатели, компилятор использует предоставленный индекс для выполнения арифметики указателя для доступа к элементам. Я понимаю, что эта процедура отличается от от статически объявленного массива до динамически объявленного массива при прохождении первого измерения.
Если я должен был объявить массив в стеке следующим образом:
  int array[2][3] = { 0, 1, 2, 3, 4, 5 }
  //In memory        { row1 } { row2 }
Этот массив будет храниться в формате Row Major в памяти, поскольку он хранится в непрерывном блоке памяти. Это означает, что когда я пытаюсь получить доступ к элементу в массиве, компилятор должен выполнить некоторое сложение и умножение, чтобы определить правильное местоположение.
Итак, если бы я сделал следующее
  int x = array[1][2]; // x = 5
Затем компилятор будет использовать эту формулу где:
i = индекс строки j = индекс столбца n = размер одной строки (здесь n = 2) 
array = указатель на первый элемент
  *(array + (i*n) + j)
  *(array + (1*2) + 2)  
Это означает, что если я должен был перебрать этот массив для доступа к каждому из его элементов, для каждого доступа по индексу выполняется дополнительный шаг умножения.
Теперь, в массиве, объявленном в куче, парадигма отличается и требует многоступенчатого решения. Примечание. Я мог бы также использовать новый оператор С++ здесь, но я считаю, что нет никакой разницы в том, как представлены данные.
  int ** array;
  int rowSize = 2;
  // Create a 2 by 3 2d array on the heap
  array = malloc(2 * sizeof(int*));
  for (int i = 0; i < 2; i++) {
      array[i] = malloc(3 * sizeof(int));
  }
  // Populating the array
  int number = 0;
  for (int i = 0; i < 2; i++) {
      for (int j = 0l j < 3; j++) {
          array[i][j] = number++;
      }
  }
Поскольку массив теперь динамический, его представление представляет собой одномерный массив одномерных массивов. Я попытаюсь нарисовать изображение ascii...
              int *        int int int
int ** array-> [0]          0   1   2
               [1]          3   4   5
Это означает, что умножение больше не задействовано? Если бы я сделал следующее
int x = array[1][1];
Затем будет выполняться арифметика косвенности/указателя на массиве [1], чтобы получить доступ к указателю на вторую строку, а затем выполнить это еще раз, чтобы получить доступ ко второму элементу. Правильно ли я это говорю?
Теперь, когда есть какой-то контекст, вернемся к вопросу. Если я пишу код для приложения, для которого требуется четкая производительность, например игра, которая имеет около 0,016 секунды для рендеринга фрейма, я должен дважды подумать об использовании массива в стеке против кучи? Теперь я понимаю, что для использования malloc или нового оператора существует однократная стоимость, но в определенный момент (как и анализ Big O), когда набор данных становится большим, лучше ли было бы переходить через динамический массив, чтобы избежать значительного числа строк индексация?
