2011-07-16 12 views
3

私はさまざまなプログラミング言語と開発プラットフォームを比較しています。 Objective-Cと他の言語との重要な違いの1つは、セレクタ、メッセージを使用することで、毎回objc_msgSendを呼び出し、共有ライブラリの境界を越えて、測定可能なオーバーヘッドと、objc_msgSend http://www.mulle-kybernetik.com/artikel/Optimization/opti-3.html 私は専門家ではないので、私はこのフォーラムにあるこの記事を信頼しなければなりません。 公式のアップルのガイドで私は "ドットシンタックス"がちょうど "構文的な砂糖"であることがわかります、それは同じメソッド呼び出しメカニズムが使われています。 質問:クラスインスタンス内で純粋な呼び出しが実行されるかどうかを知りたい場合は、objc_msgSendを呼び出すのが無駄になります。つまり、1つのクラスインスタンスのメソッドが同じクラスインスタンスのメソッドから呼び出されたときです。 ありがとうobjective-c:セレクタまたは純粋な呼び出しでまだクラス内を呼び出すメソッドですか?

答えて

1

すべてのobjective-Cメソッド呼び出しでは、obj_msgSendが使用されます。これはコードが実際の実際のクラス(self)を知らないためです。つまり、別の実装を持つサブクラスでも、たとえばxmlrpc経由でリモートマシンによって実装されるメソッドのプロキシでもかまいません。

AFAIKあなたは、メッセージXをオブジェクトYに頻繁に送信しようとしている場合、指定されたオブジェクトのセレクタの実装を取得することで、自分自身を最適化できます。

+0

IMPを参照してください。クラス内のすべての呼び出しでこれを行うのはどんな混乱ですか?しかし、コンパイラーはインスタンスがコンパイル時にそれ自身を呼び出すことを理解できませんか?非常に奇妙な。つまり、セレクタ構文を使用して同じインスタンスのメソッドを呼び出す必要はありません。 – P5music

+1

@ P5music:C++の場合でも、クラスのメンバー関数の実装内部からのクラスの仮想メソッドの呼び出しは、仮想関数テーブルを経由します。 Objective-Cでは、すべてのメソッド呼び出しは仮想です。したがって、 'objc_msgSend'ファシリティを呼び出します。心配しないで、Appleは「objc_msgSend」が絶対に重要だと知っていますので、手作りのアセンブリとたくさんのハッキングを使って完全に調整するために多くの努力を払っています。 – Yuji

4

は、仮想的なOOP言語でこのような状況を考えてみましょう:

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(); 

万一bAまたはを印刷? do_somethingの実装におけるsay_somethingの呼び出しがvtable(C++)またはobj_msgSend(Obj-C)の場合はBと表示されますが、コンパイラが同じクラスのメソッドの呼び出しで同じクラスのメソッドであれば、Aを出力します。

これは望ましい状況によって異なります。したがって、C++では、メンバー関数virtualをマークすることで、選択肢を持つことができます。 Objective-Cでは、すべてのメソッドが仮想です。

したがって、C++でも、提案した最適化は仮想メソッドには行われません。私は仮想メソッドなしで適切なOOP言語を言いません。

とにかく、Obj-Cアプリケーションのパフォーマンスが低下すると心配するかもしれません。 Appleは危険を知っているので、たくさんの最適化があります。たとえば、最近のランタイムではobjc_msgSendが固定アドレスに存在するため、まず共有ライブラリの境界を通過する必要はありません。

ミュールキバネティックスの記事も素晴らしかったですが、それは非常に年代が古いことにも注意してください。これは10年前のことです。これは、このビジネスの前史時代です。 objc_msgSendの実装に最近追加された最適化については、bbum's blog postsまたはHamster's blog postsで読むことができます。

UIを管理するコードを作成する場合は、標準のメッセージング(つまり、舞台裏でobjc_msgSend)は完全に適切です。モバイル機器でも非常にスムーズに動作します。だから、コードの性能を測定した後で絶対に必要になるまで、IMPなどを取得して早すぎる最適化をしないでください。

たとえば、数万の粒子が動いている計算集約的なコードを書いているなら、私はObj-Cメッセージングフレームワークの使用についてアドバイスをします。その場合は、Objective-C++で使用できるCコード(Objective-Cでは常に使用可能)またはC++コード(Objective-C++で使用可能)を記述するだけです。

0

objc_msgSendおよびバリアントによる動的ディスパッチを引き続き使用します。

理想的には、JITに似たものがobjcタイプに対して生成されます。

にObjCとは異なり、C++コンパイラ ++、Cへの呼び出しのために、それはタイプを決定することができたときに仮想をマークされているタイプを静的ディスパッチを使用することができます。

どのような方法でも、最適化する方法はたくさんあります.C++で実装してから、objcを使うと便利ですが、正確に何を達成しようとしているのか分かりません。

関連する問題