web-dev-qa-db-ja.com

.NETリフレクションの「コスト」とは何ですか?

可能性のある複製:
。NETリフレクションのコストはどれくらいですか?

私は現在、リフレクションが私の親友であるというプログラミングの考え方にいます。厳密なインターフェイスではなく、「緩やかな実装」を可能にするコンテンツの動的な読み込み、および多くのカスタム属性に多く使用します。

リフレクションを使用するための「実際の」コストはいくらですか?

頻繁にリフレクトされた型が、テーブル定義に対するすべてのプロパティに対する独自のLINQ DALオブジェクトコードなど、リフレクションをキャッシュするのに努力する価値はありますか?

キャッシュメモリのフットプリントは、リフレクションのCPU使用率を上回るでしょうか?

70
Tom Anderson

Reflectionでは、大量のタイプメタデータを読み込んで処理する必要があります。これにより、メモリのオーバーヘッドが大きくなり、実行が遅くなる可能性があります。 この記事 によると、プロパティの変更は約2.5x-3x遅く、メソッド呼び出しは3.5x-4x遅いです。

優れた MSDN記事 は、リフレクションを高速化する方法とオーバーヘッドの場所を示しています。詳細を知りたい場合は、読むことを強くお勧めします。

また、コードにリフレクションが追加される複雑さの要素があり、コードを大幅に混乱させ、操作が難しくなります。 Scott Hanselman などの一部の人々は、リフレクションを使用すると、解決するよりも多くの問題が発生することが多いと考えています。これは、チームのほとんどがジュニア開発者である場合に特に当てはまります。

多くの動的な動作が必要な場合は、DLR(動的言語ランタイム)を調べた方がよい場合があります。 .NET 4.0の新しい変更により、その一部をソリューションに組み込むことができるかどうかを確認できます。 VBおよびC#からの動的サポートの追加により、動的コードの使用が非常にエレガントになり、独自の動的オブジェクトをかなり簡単に作成できます。

幸運を。

編集:私はスコットのサイトをもっと調べてみたところ、リフレクションで podcast が見つかりました。私はそれを聞いていませんが、それは価値があるかもしれません。

56
smaclell

リフレクションを高速化するためにできることがたくさんあります。たとえば、多くのプロパティアクセスを実行している場合、 HyperDescriptor が役立つ場合があります。

多くのメソッド呼び出しを行っている場合、Delegate.CreateDelegateを使用して、型指定されたデリゲートにメソッドをキャッシュできます。これにより、型チェックなどが1回だけ実行されます(CreateDelegate中)。

多くのオブジェクトを構築している場合、Delegate.CreateDelegateは役に立ちません(コンストラクターで使用できません)-(3.5では)Expressionを使用してこれを行うことができます。再度型付きデリゲートにコンパイルします。

そのため、はい:反射は遅いですが、あまり苦労することなく最適化できます。

17
Marc Gravell

特にJr Devsのすばらしいリンクとすばらしいコメントに感謝します。

私たちにとって、ジュニア開発者はこれを行うのが簡単です:

[TableName("Table")]
public class SomeDal : BaseDal
{
    [FieldName("Field")]
    public string Field
}

dALのより大きな実装よりも。これにより、DALオブジェクトの構築が高速化され、上級開発者が根絶するためのすべての内部作業が隠されます。

あまりにも悪いLINQが以前に出てこなかったので、時々それの半分を書きました。

2
Tom Anderson

大きな力には大きな責任が伴います。

おっしゃるように、リフレクションにはコストがかかります。リフレクションの量によっては、アプリケーションが大幅に遅くなる可能性があります。

アプリケーションを使用するのに非常に適切な場所の1つは、アプリケーションのサイズに応じて、IoC(制御の反転)がおそらくよりも多くの利点があるためです。

2
Llyle

リフレクションを使用しているときに時々噛みつくことの1つは、リファクタリングを行うときにリフレクションを使用して呼び出しを更新しないことです。 resharperなどのツールは、メソッド名を変更するとコメントと文字列を更新するように要求するため、ほとんどの方法でそれらをキャッチできますが、動的に生成されたメソッドまたはメソッド名が動的に生成されたメソッドを呼び出すと、何かを逃します。

唯一の解決策は、適切なドキュメントと徹底した単体テストです。

0
jonnii