2010-06-02 5 views
0

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

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

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. Например, я мог бы собрать связанный список и использовать блок для обработки следующей задачи. Получу ли я что-нибудь от этого или это действительно больше проблем, чем его ценность?

+1

Вам не нужно проверять, является ли 'eachTask' не равным нулю. 'responsesToSelector:' приведет к НЕТ, если 'eachTask' равен нулю или не отвечает на' execute'. – dreamlax

+2

В любом случае вы не получите значение «nil» из NSArray. – kperryua

+2

'id *' здесь не так – newacct

ответ

6

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

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

+0

+1 хорошая статья – shosti

+0

спасибо! отличная статья! – pxl

+0

просто добавление к моему комментарию ... Мне нравится входить в мужество, а документация на яблоко идет только до сих пор ... так что это действительно отличная статья! – pxl

0

Что сказал rynmrtn ...

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

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

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

+0

Я, вероятно, должен был использовать псевдокод, но идея идет через список тысяч объектов и вызывает метод для каждого из них – pxl

0

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

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

+0

спасибо! из комментариев и того, что я читаю самостоятельно, я действительно не должен сильно беспокоиться об objc_msgSend и просто выходить из того, что работает. Затем, как вы предлагаете, выполните тесты производительности и начните поиск, где все узкие места и медленные точки. – pxl

Смежные вопросы