Влияет ли на производительность добавление категорий в класс

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

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

3 ответов


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

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


в общем, нет.

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

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

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

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

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

Читайте также:

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

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


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

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

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

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