Имеет ли вспомогательная переменная с указателем какое-либо влияние производительности/памяти?

Это?

Обычно я выбираю это,

NSArray * monthsForChosenYear = [self monthsForYear:newChosenYear];
[self setMonths: monthsForChosenYear];

При этом

[self setMonths: [self monthsForYear:newChosenYear]];

В основном, потому что это легко понять с первого взгляда. Где второй подход, не так много.

Но каковы на самом деле последствия этого? monthForChosenYear - это просто указатель, но он должен быть каким-то образом сохранен.

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

Даже переадресация на какой-либо документ, объясняющий более подробно, будет приятной.

Заранее благодарю вас!

Нуну

3 ответа

Долгий ответ, надеюсь, успокоить ваше любопытство, и любопытство хорошее! Влияние производительности и памяти равно нулю или минимально. Вы задаетесь вопросом, как хранится указатель. При вводе:

NSArray * monthsForChosenYear;

Вы запрашиваете поле (переменную), на которое должно ссылаться имя monthsForChosenYear, которое должно быть выделено в локальном хранилище. Этот флажок будет автоматически возвращен, когда метод закрытия завершится и, возможно, раньше, если компилятор выяснит, что он больше не нужен. Этот блок может содержать значение типа NSArray *.

При вводе:

NSArray * monthsForChosenYear = [self monthsForYear:newChosenYear];

Вы просите две вещи, это просто сокращение для:

NSArray * monthsForChosenYear;
monthsForChosenYear = [self monthsForYear:newChosenYear];

а вторая строка вызывает метод и сохраняет возвращаемое значение в поле с именем monthsForChosenYear. Наконец, когда вы печатаете:

[self setMonths: monthsForChosenYear];

значение, сохраненное в вашем поле monthsForChosenYear, передается методу. Если вы больше не используете ящик monthsForChosenYear, компилятор может его вернуть, или он может подождать до конца прилагаемого метода или другой подходящей точки.

Компиляторы анализируют использование ящиков и оптимизируют, иногда они даже не выделяют ящик, если он определен, не нужен. Стоимость выделения ящика бесконечно мала.

* [Примечание: на самом деле обычно есть два вида локальных ящиков. Второй, часто называемый регистром, имеет стоимость распределения, которая обычно даже меньше, чем бесконечно малая. Какой тип ящика используется компилятором.] *

При вводе:

[self setMonths: [self monthsForYear:newChosenYear]];

Вы запрашиваете два метода для вызова в одной строке, а значение, возвращаемое из внутреннего вызова ([self monthsForYear:newChosenYear]), должно быть передано внешнему вызову. Где компилятор сохраняет этот результат? Фактически, компилятор переводит приведенное выше:

NSArray *compilerTemporaryBox = [self monthsForYear:newChosenYear];
[self setMonths:compilerTemporaryBox];

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

Итак, после всего, что общий ответ, не имеет значения, как вы его пишете.

Кроме того, вы используете тип управления памятью: MRC, ARC или GC; не повлияет на ответ - компилятор будет обрабатывать оба варианта одинаково.

Итак, ищите стиль, который вы найдете лучше всего для вас. НТН.


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


Используете ли вы ARC? Без ARC с приличным оптимизатором это не будет иметь никакого значения, но с ARC он может использовать дополнительный удержание/освобождение.

licensed under cc by-sa 3.0 with attribution.