6

一部の人々は、dynamicキーワードで導入されたC#4.0の機能は、VBの「すべてがオブジェクトである」機能と同じであると主張しています。ただし、動的変数の呼び出しは一度デリゲートに変換され、それ以降、デリゲートが呼び出されます。VBでは、を使用する場合Object、キャッシュは適用されず、型指定されていないメソッドでの各呼び出しには、内部でのリフレクションが大量に含まれ、合計で400倍のパフォーマンスペナルティが発生することがあります。

動的型デリゲート最適化とキャッシングもVBの型指定されていないメソッド呼び出しに追加されましたか、それともVBの型指定されていないオブジェクトはまだ非常に遅いですか?

4

3 に答える 3

5

解決

ハンス・パッサントが言及した以前に言及された記事のいくつかの研究とより良い読みは、次の結論をもたらします:

  • VB.NET2010はDLRをサポートしています。
  • ダイナミクスを明示的にサポートする場合は実装IDynamicMetaObjectProviderできます。VB.NETコンパイラはそれを認識するように更新されます。
  • VBは、オブジェクトが;Objectを実装している場合にのみ、DLRとメソッドのキャッシュを使用します。IDynamicMetaObjectProvider
  • BCLおよびFrameworkタイプは実装されていません。そのようなタイプIDynamicMetaObjectProviderで使用Objectするか、独自のタイプを使用すると、従来のキャッシュされていないVB.NETレイトバインダーが呼び出されます。

背景:遅延バインディングキャッシングがVBコードのパフォーマンスに役立つ理由について詳しく説明する

一部の人々(Hans Passantの中で、彼の答えを参照)は、遅延バインディングでのキャッシングまたは非キャッシングがなぜ問題になるのか疑問に思うかもしれません。実際、VBと他の遅延バインディングテクノロジの両方で大きな違いがあります(IQueryInterfaceCOMを覚えていますか?)。

遅延バインディングは、単純な原則に帰着します。名前とそのパラメーター宣言を指定すると、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:優れたパフォーマンスプロファイラーがあり、コンパイラーによって遅延バインディングが内部でどのように実装されているかを知らない限り、遅延バインディングのパフォーマンスの問題を追跡するのは非常に困難です。

于 2010-06-01T10:19:57.270 に答える
2

新記事からの引用:

Visual Basic 2010が更新され、後期バインダーでDLRを完全にサポートするようになりました

それ以上に明確にすることはできません。キャッシングを実装するのはDLRです。

于 2010-04-13T11:53:56.450 に答える
0

良い質問。MSDNマガジンのこの記事では、VB.Netが動的言語ランタイムをサポートするように変更され、ランタイムの変更について簡単に説明しているが、キャッシングについては触れていない ため、答えは「いいえ」だと思います。

誰かもっとよく知っていますか?

于 2010-04-13T10:58:38.043 に答える