Приемлемо использовать прямой доступ IVAR извне класса для эффективности?
-
28-10-2019 - |
Вопрос
Я могу определить класс со свойством, чтобы получить доступ к моим Ивансам извне класса.
Я также могу просто использовать синтаксис MyInst-> ivar для доступа в C-структуре.
В C ++ я бы пошел с наборами, но в Objective-C есть некоторые случаи, когда я могу захотеть прямой доступ. Система обмена сообщениями входит в значительный удар с аксессуаром, который имеет значение в некоторых контекстах, поскольку сообщение не вставлено, как это может быть с помощью методов C ++.
Например, в классе, в котором есть ivar, называемый скаляр и свойство, определенное на нем. Скаляр - это простое значение поплавка:
-(void) doWorkWithMyClass:(MyClass*)myinst
{
// array and other locals declaration omitted
for (int i = 0; i < reallyBigX; i++) {
result += [myinst scalar] * array[i];
[myinst computeNextScalar:i];
}
}
Если я изменю [MyInst Scalar] на MyIinst-> Scalar, метод будет работать намного быстрее, поскольку использование вызовов с помощью доклада будет занимать большую часть процессора в этом цикле.
Как и в случае с C ++, я понимаю, что прямой доступ IVAR в целом обескуражен, но в этом контексте, когда скорость имеет значение, является ли это приемлемой? Если нет, есть ли более предпочтительный метод, который по-прежнему использует класс Objective-C?
Решение
Многие вещи становятся приемлемыми, когда это оказывает значительное влияние на производительность, но в примере вы даете, есть гораздо лучшие решения.
Во -первых, почему нет [myinst computeNextScalar:i]
вернуть новый скаляр? Если бы вы это сделали, вам не нужно было бы его приносить, и все было бы намного быстрее.
Не может быть перемещена в работу в myinst
? Я имею в виду, вы не можете создать что -то вроде:
result = [myinst totalOverArray:array];
Если reallyBigX
действительно большой, тогда вы должны рассмотреть Accelerate.FrameWork здесь. Это может значительно повысить производительность в отношении операции, которую вы, кажется, выполняете. (Вы должны провести тестирование производительности с помощью рамки ускорения. Это может быть существенно медленнее для некоторых операций, но этот может быть быстрее.)
Наконец, рассмотрим объектив-C get...
шаблон. Похоже:
int *scalars = calloc(reallyBigX, sizeof(int));
[myinst getScalars:scalars range:NSMakeRange(0, reallyBigX)];
for (int i = 0; i < reallyBigX; i++) {
result += scalars[i] * array[i];
}
free(scalars);
Кстати, вышеупомянутое определенно является кандидатом на vDSP_dotpr()
, хотя вы должны испытать его. Во многих случаях простая петля быстрее, чем эквивалент vDSP
вызовите при stride = 1 (так как вы можете использовать простой приращение, а не += stride
).
Другие советы
Да, это приемлемо: @public
, @private
, и т. д. Модификаторы доступа были введены частично для поддержки конструкций, где требуется доступ к ivars извне класса. Вы должны избегать писать непосредственно на Ivars, хотя.