Сколько накладных расходов несет вызов msg_send? - PullRequest
1 голос
/ 03 июня 2010

Я пытаюсь собрать воедино и запустить список задач, составленных пользователем. Эти списки задач могут состоять из сотен или тысяч элементов.

Из того, что я знаю, самый простой и очевидный способ - создать массив, а затем выполнить итерацию по ним:

NSArray *arrayOfTasks = .... init and fill with thousands of tasks

for (id *eachTask in arrayOfTasks)
{
  if ( eachTask && [eachTask respondsToSelector:@selector(execute)] ) [eachTask execute];
}

Для настольного компьютера это может быть не проблемой, но для iphone или ipad это может быть проблемой. Это хороший способ сделать это, или есть более быстрый способ сделать то же самое?

Причина, по которой я спрашиваю о том, сколько накладных расходов происходит в msg_send, заключается в том, что я также мог бы выполнять прямую реализацию на C. Например, я мог бы собрать связанный список и использовать блок для выполнения следующей задачи. Получу ли я что-нибудь от этого или это действительно больше проблем, чем стоит?

Ответы [ 3 ]

7 голосов
/ 03 июня 2010

Полагаю, вы говорите о objc_msgSend, и в этом случае Билл Бамгарнер отлично 4 Part Series , которую стоит прочитать.

В общем, я бы рекомендовал просто использовать Obj-C. Это то, что используют все приложения для iDevices, включая Apple, и сотни элементов не убьют устройство.

1 голос
/ 03 июня 2010

Здесь - хорошее сравнение стандартных операций, включая objc_msgSend. В общем, вам не стоит беспокоиться о производительности objc_msgSend даже на iPhone. Отправка сообщений всегда будет медленнее, чем прямой вызов функции C, но на современном процессоре (помните, процессор iPhone по-прежнему составляет около 500 МГц), разница в большинстве случаев тривиальна. Если профилирование показывает, что в objc_msgSend используется много времени, возможно, стоит использовать прямые функции C вместо методов Objective-C.

Для ясности вы можете использовать -[NSArray makeObjectsPerformSelector:] или (на Mac) enumerateObjectsUsingBlock: вместо итерации по объектам, но я не думаю, что это должно сильно влиять на производительность.

1 голос
/ 03 июня 2010

Что сказал Ринмртн ...

Если ваши -execute методы не были чрезмерно упрощенными - увеличивать / тестировать небольшую горстку скалярных значений - тогда маловероятно, что objc_msgSend() будет отображаться как% времени ЦП вашей программы.

Сначала измерьте, затем оптимизируйте.

Ваш код вызывает вопрос; почему вы кладете вещи в arrayOfTasks, которые не могут execute. Предполагая, что все в вашем arrayOfTasks является подклассом вашего создания, вы можете добавить метод execute и не выполнять тест отвечает . Если у вас есть иерархия классов коллекций, вы можете использовать категории для добавления методов - просто добавьте к ним префикс, чтобы быть в безопасности (т.е. pxl_execute или что-то в этом роде).

...