Хит производительности self.instance_var? - PullRequest
0 голосов
/ 20 февраля 2010

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

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

Например:

NSMutableArray *mFoo;
@property(nonatomic, retain) NSMutableArray *mFoo;
@synthesize mFoo;

-(void)someMethod {
    Bar* b;
    for (int i=0; i<10000; i++) {
        b = [self.mFoo objectAtIndex:i];   // <<<<<<<<<<<<<<<<
        if (b.something == 123) { // do something };
    }
 }

Ответы [ 3 ]

4 голосов
/ 20 февраля 2010

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

Всегда используйте средства доступа. Всегда . Никогда не захватывайте значения напрямую, рассматривая объект как структуру. Это нарушает инкапсуляцию и т. Д. И т. Д. И т. Д. ...

(Имейте в виду, что self.mfoo является точно синонимом с [self mfoo] в следующем обсуждении).

Теперь, в этом случае, ваша очевидная оптимизация - переместить self.mfoo за пределы цикла. Используйте синтаксис for(Bar *b in self.mfoo), как предложил мистер Маг.

Реальный вопрос, однако, заключается в том, Измеряли ли вы производительность вашего приложения и определяли ли , что конкретный вызов метода действительно вызывал какие-либо существенные издержки?

Если так, оптимизируйте. Скорее всего, в общей схеме вещей нет измеримых накладных расходов.

3 голосов
/ 20 февраля 2010

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

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

Итак:

CGSize sz = [self size]; //ok
CGSize sz = self.size; //ok
CGSize sz = _size; //ok, but be careful

[self setSize:sz]; //ok
self.size = sz, //ok
_size = sz; // DON'T EVER DO THIS!

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

0 голосов
/ 20 февраля 2010

Для каждого доступа к self.mFoo, если бы была включена быстрая диспетчеризация сообщения Objective C (если бы компилятор не оптимизировал этот вызов), пришлось бы вызывать около одной функции C Таким образом, удар по производительности не будет заметен в большинстве случаев. В приведенном выше примере вы должны использовать быстрое перечисление, например

for (Bar *b in self.mFoo) {
    // do whatever you wish to here
}

, что приведет к доступу к self.mFoo только один раз и в целом будет быстрее (например, если ваш массив действительно является списком).

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