Какова разница в производительности между блоками и обратными вызовами?

Одна из вещей, которые блокируют объекты, введенные в Snow Leopard, хороши для ситуаций, которые ранее обрабатывались с помощью обратных вызовов. Синтаксис намного проще для передачи контекста. Тем не менее, я не видел никакой информации об эффектах, связанных с использованием блоков таким образом. Что, если таковые имеются, проблемы с производительностью, на которые я должен обратить внимание при использовании блоков, особенно в качестве замены обратного вызова C-стиля?

Ответ 1

Время выполнения блоков довольно жесткое. Блокированные дескрипторы и функции статически распределены, поэтому они могут увеличить рабочий набор вашей программы, но вы только "платите" в хранилище за переменные, которые вы ссылаетесь из охватывающей области. Неглобальные блок-литералы и переменные __block построены в стеке без какого-либо ветвления, поэтому вы вряд ли столкнетесь с большей частью замедления. Вызов блока - это просто result = (*b->__FuncPtr)(b, arg1, arg2); это сопоставимо с result = (*callback_func_ptr)(callback_ctx, arg1, arg2).

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

Ответ 2

Возможно, вы захотите проверить этот пост в блоге и этот. Блоки реализованы как объекты Objective-C, за исключением того, что они могут быть помещены в стек, поэтому они необязательно должны быть malloc 'd (если вы сохраните ссылку на блок, она будет скопирована в кучу, хоть). Таким образом, они, вероятно, будут работать лучше, чем большинство объектов Objective-C, но будут иметь небольшое увеличение производительности по сравнению с простым обратным вызовом - я предполагаю, что это не должно быть проблемой в 95% случаев.