ViewDataとViewBagはどちらも同じバッキングデータを使用し、どちらもほとんどの場合、厳密に型指定されたモデルを使用するのと同じくらい優れていることは知っています。ただし、2つを選択する場合、ViewBagの動的な性質はViewDataを使用するよりも遅くなりますか?
わかりました-私の最初の答えは基本的に「いいえ」-少しのUターンの時間です.
完全な動的な世界ではすべきではありませんですが、詳しく調べると、違いがない(JITマジックの説明)か、またはmight使用することを保証するのに十分ではありませんが、少し遅くなる可能性があります(確かにそうです).
理論的には適切に実装されている場合、式のバインディング(たとえばViewBag.Foo
)はさまざまな方法で非常によくキャッシュされるため、ViewBagは最終的にViewDataディクショナリの使用を上回ります CallSite sコンパイラが生成します(ViewBag
に対して読み取りまたは書き込みを行うメソッドを反映すると、私の意味がわかります)。
DLRのキャッシングレイヤー 十分に文書化されています (詳細を理解すると少し理解が難しい場合)ただし、基本的にランタイムは、指定された値のインスタンスがバインドされた場所を「記憶」するために最善を尽くします-たとえば、SetまたはGetステートメントを介して。
[〜#〜] but [〜#〜]キャッシング、その使用法および効果は、次のようなクラス/インターフェースの基礎となる実装に完全に依存しています DynamicObject 、 IDynamicMetaObjectProvider など; Get/Set式バインディングの最終結果と同様に。
MVC内部DynamicViewDataDictionaryクラスの場合-最終的にこれにバインドします。
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = this.ViewData[binder.Name];
return true;
}
var a = ViewBag.Foo
そして
public override bool TrySetMember(SetMemberBinder binder, object value)
{
this.ViewData[binder.Name] = value;
return true;
}
ViewBag.Foo = Bar;
言い換えると、ステートメントは事実上、辞書インデクサーのラッパーに書き換えられています。
そのため、自分でそれを行うよりも速くできる方法は確かにありません。
ViewData
はViewBag
からフィードするのではなく、逆にして、ViewBag
は ExpandoObject
のようなものでも実装されました 、それは別の話かもしれません- ExpandoObject
の動的実装ははるかにインテリジェントであり、それが採用するキャッシュルールはかなりクールなランタイム最適化を可能にします。
(必要だったと示唆してくれたShawn McLeanに感謝!)
ViewBagはViewDataよりも遅くなります。しかし、おそらく懸念を表明するのに十分ではありません。
私はまだテストを行っていませんが、私の直感は、実際のシナリオでは違いはごくわずかであるということです。おそらく、各ページで数回アクセスしますが、CPUサイクルが少しであっても違いはありません。他の場所でより大きなパフォーマンスの改善を見つけることができます。