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