Прямой доступ к элементу массива или присвоение его переменной - PullRequest
6 голосов
/ 20 августа 2011

С точки зрения производительности, лучше ли обращаться к элементу массива «напрямую» несколько раз или присваивать его значение переменной и использовать эту переменную? Предполагая, что я буду ссылаться на значение несколько раз в следующем коде.

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

// use a variable to store the value
Temp = ArrayOfValues(0)
If Temp > 100 Or Temp < 50 Then
    Dim Blah = Temp
    ...

// reference the array element 'directly'
If ArrayOfValues(0) > 100 Or ArrayOfValues(0) < 50 Then
    Dim Blah = ArrayOfValues(0)
    ...

Я знаю, что это тривиальный пример, но предположим, что мы говорим о большем масштабе в реальном использовании (где значение будет указываться много раз), в какой момент стоит рассмотреть компромисс между пространством и вычислительным временем (если при все)

Ответы [ 2 ]

3 голосов
/ 20 августа 2011

Это помечено языком, но я действительно не верю, что это так.Этот пост отвечает на вопрос на C и C ++.

Оптимизирующий компилятор может позаботиться о доступе к «голому» массиву;в C или C ++ нет причин полагать, что компилятор не запомнит значение ячейки памяти, если между ними не было вызвано ни одной функции.Например,

int a = myarray[19];
int b = myarray[19] * 5;
int c = myarray[19] / 2;
int d = myarray[19] + 3;

Однако, если myarray не просто определен как int [], но на самом деле является чем-то «причудливым», особенно некоторый определенный пользователем тип контейнера с функцией operator[](), определенной в другой единице перевода, то этофункция должна вызываться каждый раз, когда запрашивается значение (поскольку функция возвращает данные в определенном месте в памяти, а локальная функция не знает, что результат функции должен быть постоянным).

Хотя даже с «голыми» массивами, если вы обращаетесь к одной и той же вещи несколько раз при вызове функций, компилятор также должен предположить, что значение было изменено (даже если он может запомнить сам адрес).Например,

int a = myarray[19];
NiftyFunction();
int b = myarray[19] * 8;

Компилятор не может знать, что myarray [19] будет иметь одинаковое значение до и после вызова функции.

Вообще говоря, если вы знаете, чтозначение является постоянным в локальной области видимости, «кеширует» его в локальной переменной.Вы можете программировать с защитой и использовать утверждения для проверки того условия, которое вы наложили на вещи:

int a = myarray[19];
NiftyFunction();
assert(myarray[19] == a);
int b = a * 8;

Последнее преимущество заключается в том, что намного проще проверять значения в отладчике, если они не похоронены вмассив где-то.

2 голосов
/ 20 августа 2011

Затраты на потребление памяти очень ограничены, поскольку для ссылочных типов это просто указатель (пара байтов), а большинству типов значений также требуется всего несколько байтов.

Массивы являются очень эффективными структурами в большинстве языков.Переход к индексу не требует какого-либо поиска, а просто требует математики (каждый слот массива занимает 4 байта, поэтому 11-й слот имеет смещение 40).Тогда, вероятно, есть некоторые накладные расходы для проверки границ.Выделение памяти для нового локального var и освобождение его требует также немного циклов процессора.Таким образом, в конечном итоге это также зависит от того, сколько поисков в массиве вы исключаете, копируя в локальную переменную.

Факт в том, что вам действительно нужно исключительно дрянное оборудование или действительно большие циклы, чтобы это было действительно важно, и если это такпровести достойный тест на нем.Лично я часто выбираю отдельную переменную, поскольку считаю, что она делает код более читабельным.

Ваш пример странный, кстати, поскольку вы делаете 2 поиска в массиве, прежде чем создавать локальную переменную :) Это имеет больше смысла (исключение еще 2 поиска)

Dim blah = ArrayOfValues(0)
if blah > 100 or blah < 50 then
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...