解決
ハンス・パッサントが言及した以前に言及された記事のいくつかの研究とより良い読みは、次の結論をもたらします:
- VB.NET2010はDLRをサポートしています。
- ダイナミクスを明示的にサポートする場合は実装
IDynamicMetaObjectProvider
できます。VB.NETコンパイラはそれを認識するように更新されます。
- VBは、オブジェクトが;
Object
を実装している場合にのみ、DLRとメソッドのキャッシュを使用します。IDynamicMetaObjectProvider
- BCLおよびFrameworkタイプは実装されていません。そのようなタイプ
IDynamicMetaObjectProvider
で使用Object
するか、独自のタイプを使用すると、従来のキャッシュされていないVB.NETレイトバインダーが呼び出されます。
背景:遅延バインディングキャッシングがVBコードのパフォーマンスに役立つ理由について詳しく説明する
一部の人々(Hans Passantの中で、彼の答えを参照)は、遅延バインディングでのキャッシングまたは非キャッシングがなぜ問題になるのか疑問に思うかもしれません。実際、VBと他の遅延バインディングテクノロジの両方で大きな違いがあります(IQueryInterface
COMを覚えていますか?)。
遅延バインディングは、単純な原則に帰着します。名前とそのパラメーター宣言を指定すると、Type
インターフェイスを介して使用可能なメソッド(および、VBでは、メソッド、プロパティ、およびフィールドは同じように見える可能性があり、このプロセスはさらに遅くなります)。メソッドテーブルが順序付けられていないことを考慮すると、これは単一の直接(つまり型付き)メソッド呼び出しよりも簡単にはるかにコストがかかります。
メソッドを一度ルックアップしてから、メソッドポインターをルックアップテーブルに格納できる場合は、このプロセスが大幅に高速化されます。DLRのキャッシュされたメソッドバインディングはさらに一歩進んで、可能であれば、メソッド呼び出しを実際のメソッドへのポインターに置き換えます。最初の呼び出しの後、これは後続の呼び出しごとに1桁速くなります(200倍から800倍速くなると考えてください)。
これが重要な場合の例として、この問題を説明するコードを次に示します。すべてのクラスに.Name
文字列プロパティがあり、クラスが共通の祖先またはインターフェイスを共有していない場合は、次のようにこれらのタイプのリストを単純に並べ替えることができます。
' in the body of some method '
List<Customers> listCustomers = GetListCustomers()
List<Companies> listCompanies = GetListCompanies()
listCustomers.Sort(MySort.SortByName)
listCompanies.Sort(MySort.SortByName)
' sorting function '
Public Shared Function SortByName(Object obj1, Object obj2) As Integer
' for clarity, check for equality and for nothingness removed '
return String.Compare(obj1.Name, obj2.Name)
End Function
このコード(少なくとも同様)は、実際に私のクライアントの1つで本番環境に移行し、よく呼ばれるAJAXコールバックで使用されました。.Name
すでに50万未満のオブジェクトの中規模のリストにあるプロパティを手動でキャッシュしないと、遅延バインディングコードが非常に目立つ負担になり、最終的にサイト全体がダウンしました。この問題を突き止めるのは難しいことがわかりましたが、それはまた別の話です。これを修正した後、サイトはCPUリソースの95%を取り戻しました。
したがって、ハンスの質問「心配する必要のある大きな問題はありませんか」に対する答えは単純です。これは大きな問題です(またはそうなる可能性があります)。遅延バインディングの使用に不注意になっているVBプログラマーに。
この特定のケース、およびそれらの多くの場合と同様に、VB.NET 2010は、遅延バインディングを導入するようにアップグレードされていないようです。Object
そのため、気付かないうちに悪意を持ったままであり、と比較するべきではありませんdynamic
。
PS:優れたパフォーマンスプロファイラーがあり、コンパイラーによって遅延バインディングが内部でどのように実装されているかを知らない限り、遅延バインディングのパフォーマンスの問題を追跡するのは非常に困難です。