target-c: вызов метода внутри класса все еще с селекторами или чистыми вызовами? - PullRequest
3 голосов
/ 16 июля 2011

Я сравниваю разные языки программирования и платформы разработки. Одно важное различие между target-c и другими языками состоит в том, что он использует селекторы, сообщения, поэтому каждый раз вызывая objc_msgSend, пересекая границу разделяемой библиотеки, таким образом, вводя измеримые издержки, плюс дополнительные издержки (немного в кешированном случае) для objc_msgSend внутреннее функционирование, как объяснено здесь: http://www.mulle -kybernetik.com / Код / Оптимизация / Opti-3.html Я не эксперт, поэтому я должен доверять этой статье, найденной на этом форуме. В официальном руководстве Apple я считаю, что «точечный синтаксис» - это просто «синтаксический сахар», то есть используется тот же механизм вызова метода. Вопрос: Я хотел бы знать, если вместо этого чистые вызовы выполняются внутри экземпляра класса, где было бы напрасно вызывать objc_msgSend. То есть, когда метод одного экземпляра класса вызывается из метода того же экземпляра класса. Спасибо

Ответы [ 3 ]

4 голосов
/ 16 июля 2011

Рассмотрим эту ситуацию на гипотетическом языке ООП:

class A {
     say_something(){
         print("A!")
     }
     do_something(){
         say_something()
     }
}

и

class B : extends A {
     say_something(){
         print("B!")
     }
}

Теперь предположим, что у вас есть экземпляр B и вызовите do_something:

B b;
b.do_something();

Должен ли b напечатать A или B?Если вызов say_something в реализации do_something проходит через vtable (в C ++) или obj_msgSend (в Obj-C), он напечатает B, но если компилятор решит вызватьметод в том же классе должен вызывать метод в том же классе, он напечатает A.

Что желательно, зависит от ситуации.Таким образом, в C ++ у вас может быть выбор, помечая функцию-член virtual или нет.В Objective-C каждый метод является виртуальным.

Таким образом, даже в C ++ предложенная вами оптимизация не относится к виртуальным методам.Я не скажу, что язык без виртуальных методов - это правильный язык ООП.

В любом случае, теперь вы можете опасаться, что это ухудшит производительность приложения Obj-C.Apple знает об опасности, поэтому у них есть много оптимизаций.Например, в недавней среде выполнения objc_msgSend живет по фиксированному адресу, поэтому вам не нужно сначала проходить границу разделяемой библиотеки.

Статья о Мюлле-Кибернетике тоже была приятной, но заметьте также, что она очень устарела: она колоссальная десять лет назад, что в этом бизнесе доисторическое время.Вы можете прочитать о недавних оптимизациях для реализации objc_msgSend в сообщениях в блоге bbum или сообщений в блоге Hamster .

Если вы пишете коды, управляющие пользовательским интерфейсом,использование стандартного обмена сообщениями (т. е. objc_msgSend за кадром) вполне адекватно.Это даже работает очень гладко на мобильных устройствах!Поэтому не выполняйте преждевременную оптимизацию, получая IMP и т. Д., Пока это не станет абсолютно необходимым после измерения производительности кода.

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

1 голос
/ 16 июля 2011

Все вызовы метода target-C используют obj_msgSend. Это потому, что код не знает фактический реальный класс, который self. то есть: это может быть подкласс с другой реализацией или даже прокси для метода, который реализуется на удаленной машине, например, через xmlrpc.

AFAIK, вы можете оптимизировать вещи самостоятельно, используя реализацию селектора для данного объекта, если знаете, что собираетесь часто отправлять сообщение X на объект Y.

0 голосов
/ 17 июля 2011

он все еще использует динамическую отправку через objc_msgSend и варианты.

в идеале, что-то похожее на JIT было бы создано для типов объектов.

в отличие от objc, компилятор c ++ может использовать статическую диспетчеризацию для вызовов типов c ++, помеченных как виртуальные , когда он может определить тип .

во всяком случае, есть много способов оптимизации - вы могли бы начать с реализации на c ++, а затем использовать objc там, где это действительно удобно ... но я не уверен, чего именно вы пытаетесь достичь.

...