2011-11-19 19 views
13
  1. 可能であれば、LLVMはObjective-Cメソッドをインライン関数に自動的に変換しますか?LLVMはObjective-Cメソッドをインライン関数に変換しますか?

    (すなわち、それはあなたがそうでない場合は、インライン貼り付けることができ、コードのブロックのためのObjective-Cのメソッドを作成するために同じようにパフォーマンスのですか?)

  2. LLVMは、この最適化を実行しない場合は、なぜ?もしそうなら、(a)ビルドの設定がありますか?これを設定する必要がありますか? (b)Objective-Cメソッドがインライン化されるかどうかをどのようにして知ることができますか?

答えて

12

いいえ、Obj-Cランタイムのコンテキストでは、その種の最適化が実行できるかどうかを知ることができないためです。覚えておくべきことは、Obj-Cメソッドがメッセージ送信によって呼び出されるということです。これらのメッセージは、構文以上のものから来る可能性があります。

[obj performSelector:NSSelectorFromString(@"hello")]このことが起こる可能性があるということは、どの方法でもインライン化することが不可能であることを意味します。

メッセージがクラスによって受信されたときに発生する一連のイベントもあります。これらのイベントは、ルーティングされるか、送信されるメッセージを変更することさえできます。これは、メッセージ送信の下で透過的に起こります。

+0

なぜLLVMは、普通の電話を置き換えることができない、例えば、 '[OBJ X]。例えば、 '[obj performSelector:x_sel]'等のメソッド本体を 'x'で' obj.x'と 'performSelector'呼び出しを行う?そして、 'forwardInvocation:'のようなメソッドの実装をチェックして、インライン化が必要かどうかを調べることができないのはなぜですか? LLVMを是非、スマートに! :) – ma11hew28

+7

実行時に簡単にスワップアウトできるためです。私は3行または4行のランタイムコードで任意のメソッドのimplenentafionを変更することができます。 –

9

号はそうではありません、コンパイル時に、実行時に動的に起こる(あなたがいない呼び出し方法を行うOBJの-Cにメッセージを送信ことを覚えておいてください)メッセージの発送はObjective-Cのの本質的な特徴であります時間。

このため、Obj-Cでのメッセージディスパッチは、(関数がインライン化されていなくても)純粋な関数呼び出しよりも少し遅くなります。右、速いだろうことのように思える

- (void)doBar { 
    [self doAwesomeStuff]; 
    { 
    NSLog(@"doing foo!"); 
    } 
} 

素晴らしい、:

@implementation AwesomeClass 

- (void)doFoo OBJC_INLINE { // or some way to indicate "this is an inline method" 
    NSLog(@"doing foo!"); 
} 

- (void)doBar { 
    [self doAwesomeStuff]; 
    [self doFoo]; 
} 

@end 

よう-doBarは、基本的に次のようになります。

9

はのは、コンパイラがメソッドをインライン化した瞬間のために仮定しましょうか?私たちはobjc_msgSendに電話をかけないで、1ダースの指示をすべて守ります。これをパッケージ化して、.aファイルとしてオンラインで投稿します。

NSCleverCoderがやって来ると言い、「しかし、私はdoFooはもう少しやりたい」、そう彼は:

@interface SuperAwesomeClass : AwesomeClass @end 
@implementation SuperAwesomeClass 
- (void)doFoo { 
    NSLog(@"doing more foo!"); 
    [super doFoo]; 
} 
@end 

彼はこれを実行しようと、それはと呼ばれることは決してありません、AwesomeClass決してので、実際に-doFooメソッドが呼び出されます。

「しかし、これは人為的な例です」

いいえ、そうではありません。 Objective-Cでは、アプリケーションの開発や実行のどの時点でもこれを行うことは完全に合法です。私はコードを書くときにこれを行うことができます。ちょっと、私は実行時にobjc_allocateClassPairclass_addMethodを使って動的にサブクラスを作成し、メソッドオーバーライドを追加することでこれを行うこともできます。

私はメソッドの実装もうかがいます。-doFooの既存の実装が気に入らないのですか?カッコいい;自分のものと交換してください。あ、ちょっと待って;メソッドがインライン化されている場合、-doBarは実際には-doFooメソッドを呼び出すことはないため、新しい実装は呼び出されません。

私はこの方法が可能であることがわかりました。ある方法では、オーバーライド不可能なメソッドに注釈を付けることができました。 But there's no way to do that、問題は解決されています。そしてでもの場合でも、それはまだ悪い考えです。なぜなら、コンパイラが実行させないからといって、実行時にそれを回避することができないというわけではありません。もう一度、あなたは問題に取り組むでしょう。

+0

私はにかなりくそスマートでなければならないであろうコンパイラにどのように見ることができ、私はちょうどメソッドがオーバーライドされたメソッド内で呼び出されても、オーバーライドするメソッドに挿入されているような場合を検出できるコンパイラを考えていたと思います...しかし、それを行う。それでも... ARCはかなり驚くべきことです...おそらく、メソッドをインライン化する方法を知っているもう1つのクールな機能をLLVMに追加することができます。 – ma11hew28

関連する問題