Влияет ли на производительность добавление категорий в класс? - PullRequest
9 голосов
/ 24 августа 2009

Я новичок в Какао и у меня небольшой вопрос, прежде чем я увлекся использованием категорий.

Допустим, вы добавили новый метод в NSString. Влияет ли это на производительность обычных сообщений NSString или методы категории проверяются только тогда, когда вызов метода не соответствует стандартному набору методов?

Ответы [ 3 ]

8 голосов
/ 24 августа 2009

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

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

7 голосов
/ 30 августа 2009

В общем, нет.

objc_msgSend() хранит псевдо-наименьший недавно использованный кеш самых последних поисков от SEL до IMP для каждого класса. Как всегда, специфика - это «частные детали реализации», но разумно сказать, что время поиска составляет в среднем ~ O(1), независимо от количества селекторов. Наиболее распространенный способ сделать это - с помощью небольшой хеш-таблицы - если селектор находится в кеше, тогда отправка происходит по существу мгновенно. Если селектор отсутствует в кэше, он должен выполнить дорогой поиск по «медленному пути».

Однако даже «медленный путь» может быть достаточно быстрым. Существует любое количество структур данных, к которым можно обратиться, таких как «Красные черные деревья», которые предлагают превосходные субэкспоненциальные времена поиска, которые хорошо масштабируются независимо от количества селекторов - как правило, в диапазоне O(log2(selectorCount)). Опять же, то, как libobjc имеет дело с подобными деталями, является частным, но существует так много структур данных, которые легко масштабируются независимо от количества элементов для поиска, поэтому нет никаких причин, по которым подобные вещи должны даже присутствовать на вашем радаре.

Быстрая проверка с помощью nm включает 7771 селекторов в Foundation и 27510 селекторов в AppKit, в общей сложности 35281 селектор только между двумя. Добавьте QuickTime, CoreData, WebKit, Quartz, и вы получите до 50K селекторов. При увеличении времени поиска log2 удвоение количества селекторов увеличит время наихудшего случая менее чем на 10%.

В итоге: objc_msgSend() использует небольшой кеш на основе хеша для предоставления O(1) времени поиска для самых последних использованных селекторов ... и очень высокая временная локальность, поэтому подавляющее большинство отправок завершено в O(1) времени независимо от количества селекторов, присутствующих в системе. Естественный эффект кеша заключается в том, чтобы «подстраиваться» под ваши конкретные модели использования. Даже при пропадании кеша, вероятно, разумно предположить, что время поиска в худшем случае ограничено ~ O(log2(selectorCount)), что довольно хорошо, и, вероятно, лучше, чем на практике.

Для чего я стоил, я потратил много времени на настройку кода для скорости. Даже в многопоточных средах, где я привязываю все процессоры, выполняющие огромные объемы анализа -> рендеринг тяжелых результатов NSView / OpenGL, все они написаны на Objective-C, я буду видеть только то, как objc_msgSend() занимает 1-4 процента CPU когда профилируется с Shark.app ... и это худший случай, когда выполняется интенсивная диспетчеризация сообщений Objective-C. Для меня это никогда не было проблемой, и, несмотря на незначительные потери в скорости, это легко компенсируется производительностью программирования в 100 раз.

Смотри также:

Mulle kybernetiK - Оптимизация Obj-C: чем быстрее objc_msgSend
Руководство по программированию в Objective-C 2.0 - Обмен сообщениями
Apple Objective-C Runtime - objc4-437.tar.gz

EDIT : Как странно это: Патент 5960197 - Функция отправки компилятором для объектно-ориентированного C . Не могу сказать, что знал, что вся система диспетчеризации сообщений Obj-C была запатентована ... Я думаю, вы действительно можете получить патент на что угодно. Я собираюсь запатентовать алфавит и зарядить большой, детка!

4 голосов
/ 24 августа 2009

Если вы новичок в Какао, это не должно беспокоить вас. Помимо основного правила не делать предположений о производительности без профилирования.

Если вам нужно предоставить функциональность, вы можете добавить ее, где сможете. Если имеет смысл расширить класс, сделайте это. Если вы не добавите эту функциональность в NSString, вам придется предоставить ее в другом месте. Если вы делаете это в другом классе, то это добавляет другой уровень сложности.

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

И хотя здесь я делаю предположение, я бы сказал, что вероятность того, что производительность вашего приложения будет больше, чем скорость вызовов NSString. Если вы не делаете лот вызовов NSString - в этом случае мы снова возвращаемся к профилированию.

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