質問

リフレクションを使用するのがいかに悪いかを常に聞いています。私は一般的に反射を避け、それなしでは問題を解決できない状況をめったに見つけませんが、私は疑問に思っていました...

アプリケーションでリフレクションを使用したことがある人のために、パフォーマンスヒットを測定しましたが、本当にひどいですか?

役に立ちましたか?

解決

そうです。しかし、それはあなたがやろうとしていることに依存します。

リフレクションを使用して、アセンブリ(プラグイン)とそのパフォーマンス「ペナルティ」を動的に読み込みます。操作はアプリケーションの起動中に行うことなので、問題ではありません。

ただし、一連のネストされたループ内で、それぞれにリフレクション呼び出しがある場合は、コードを再検討する必要があります:)

「数時間」の場合操作、リフレクションは完全に受け入れられ、遅延や問題に気付くことはありません。これは非常に強力なメカニズムであり、.NETでも使用されているので、試してはいけない理由はわかりません。

他のヒント

彼の講演ジェフ・リヒターは、日常のパフォーマンスで、リフレクションによるメソッドの呼び出しは、通常の呼び出しよりも約 1000倍遅いことを示しています。

Jeffのヒント:メソッドを複数回呼び出す必要がある場合は、リフレクションを1回使用して検索し、デリゲートに割り当ててから、デリゲートを呼び出します。

リフレクションのパフォーマンスは実装に依存します(繰り返し呼び出しはキャッシュする必要があります。例: entity.GetType()。GetProperty(" PropName"))。日常的に見られるリフレクションのほとんどは、データリーダーまたは他のリポジトリタイプ構造からエンティティを生成するために使用されるため、オブジェクトプロパティの取得または設定に使用される場合、リフレクションのパフォーマンスを特にベンチマークすることにしました。

すべての繰り返し呼び出しをキャッシュし、実際のSetValueまたはGetValue呼び出しのみをキャッシュするため、公平だと思うテストを考案しました。パフォーマンステストのすべてのソースコードは、bitbucketの https://bitbucket.org/grenade/accessortest。精査は歓迎され奨励されています。

結論は、実用的ではなく、リフレクションの実装が適切に行われたときに100,000行未満を返すデータアクセスレイヤーのリフレクションを削除するための顕著なパフォーマンスの向上をもたらさないということです。

時間(y)のグラフエンティティの数(x)

上記のグラフは、私の小さなベンチマークの出力を示しており、反射を上回るメカニズムは、100,000サイクルのマークを過ぎて初めて顕著になります。ほとんどのDALは一度に数百またはおそらく数千の行を返すだけで、これらのレベルではリフレクションは問題なく実行されます。

ループに入っていない場合は、心配しないでください。

最も適切な経験は、大きなオブジェクトモデル内の同じタイプの2つのデータエンティティをプロパティごとに比較するコードを書くことでした。動作して、試してみて、明らかに犬のように走りました。

私は落胆し、その後一晩でロジックを変更することなく、同じアルゴリズムを使用して、比較を行うがプロパティに静的にアクセスするメソッドを自動生成できることに気付きました。この目的のためにコードを調整するのにまったく時間はかかりませんでした。オブジェクトモデルが変更されるたびにボタンをクリックするだけで更新できる静的コードとエンティティをプロパティごとに詳細に比較する機能がありました。

私のポイント:同僚との会話で、リフレクションの使用はランタイム操作を実行するのではなく、コンパイルするコードを自動生成することができると何度か指摘してきたので、これはしばしば検討する価値があります。

大規模ではありません。 Martinが述べているように、あなたが愚かな場所でそれを使用しているのでない限り、デスクトップ開発で問題が発生したことはありません。多くの人がデスクトップ開発のパフォーマンスについて全く不合理な恐れを持っていると聞いています。

Compact Framework (通常私がいる)では、かなりきれいです多くの anathema であり、ほとんどの場合、ペストのように避ける必要があります。あまり頻繁に使用しないで済ませることはできますが、アプリケーションの使用には注意が必要です。 :(

パフォーマンスが重要なコードのために、.NETライブラリによって内部的に行われるリフレクションについても心配する必要があるのは十分に悪いことです。

次の例は廃止されました-当時(2008)には当てはまりますが、以前のCLRバージョンでは修正されていました。ただし、一般に反射はまだいくらかコストがかかります!

適切な場合:" Object"として宣言されたメンバーを使用しないでください。高性能コードのロック(C#)/ SyncLock(VB.NET)ステートメント内。どうして? CLRは値型をロックできないため、オブジェクトが実際に参照型ではなく値型であるかどうかを確認するために、実行時リフレクション型チェックを実行する必要があることを意味します。

プログラミングのすべてのことと同様に、パフォーマンスコストと得られるメリットのバランスを取る必要があります。リフレクションは、注意して使用すると非常に貴重なツールです。リフレクションを使用してバインディングを行うC#でO / Rマッピングライブラリを作成しました。これは素晴らしくうまくいきました。ほとんどのリフレクションコードは1回しか実行されなかったため、パフォーマンスへの影響はほとんどありませんでしたが、メリットは大きくなりました。新しい扇形の並べ替えアルゴリズムを作成している場合、おそらくリフレクションは使用しないでしょう。

ここであなたの質問に正確に答えていないことに感謝します。私のポイントは、それは本当に重要ではないということです。必要に応じて反射を使用します。これは、使用方法と使用方法を学習するために必要な別の言語機能です。

Reflectionは、頻繁にオブジェクトを作成するために使用すると、パフォーマンスに顕著な影響を与える可能性があります。 複合UIアプリケーションに基づいてアプリケーションを開発しました反射に大きく依存しているブロック。リフレクションによるオブジェクトの作成に関連する顕著なパフォーマンスの低下がありました。

ただし、ほとんどの場合、リフレクションの使用に問題はありません。アセンブリの検査だけが必要な場合は、 Mono.Cecil をお勧めします。これは非常に軽量かつ高速

パラメータのリストに一致するメソッドをリクエストするたびにランタイムが行う必要のある多くのチェックのため、反射はコストがかかります。奥深くのどこかに、型のすべてのメソッドをループし、その可視性を検証し、戻り値の型をチェックし、各パラメーターの型もチェックするコードが存在します。これらはすべて時間がかかります。

そのメソッドを内部で実行すると、実際のターゲットメソッドを実行する前に、互換性のあるパラメーターのリストを渡したことを確認するなどの処理を行うコードがあります。

可能であれば、将来的に継続的に再利用する場合は、常にメソッドハンドルをキャッシュすることをお勧めします。すべての優れたプログラミングのヒントと同様に、繰り返しを避けることは理にかなっています。この場合、特定のパラメーターを使用してメソッドを継続的に検索し、それを毎回実行することは無駄です。

ソースを調べて、何が行われているのか見てみましょう。

すべてと同様に、状況を評価することがすべてです。 DotNetNuke には、リフレクションを使用して FillObject というかなりコアなコンポーネントがあります。データ行からオブジェクトを作成します。

これはかなり一般的なシナリオであり、MSDNに Reflectionを使用してビジネスオブジェクトをASP.NETフォームコントロールにバインドする 。パフォーマンスの問題をカバーしています。

パフォーマンスは別にして、その特定のシナリオでリフレクションを使用するのが好きではないことの1つは、コードを一目で理解する能力が低下する傾向があることです。また、強く型付けされたデータセットや LINQ  to  SQL 。

反射は、アプリのパフォーマンスを大幅に低下させることはありません。リフレクションを使用しないことで特定のことをより迅速に行える場合がありますが、一部の機能を実現する最も簡単な方法がリフレクションである場合は、それを使用します。パフォーマンスの問題になる場合は、Reflectionからコードをリファクタリングできます。

答えは次のとおりであることがわかると思います。タスクリストアプリケーションに配置する場合、大したことではありません。 Facebookの永続化ライブラリに配置したい場合は大したことです。

scroll top