我知道 ViewData 和 ViewBag 都使用相同的支持数据,并且在大多数情况下都没有使用强类型模型好。然而,在两者之间进行选择时,ViewBag 的动态特性是否比使用 ViewData 慢?
2 回答
好的——我最初的回答基本上是“不”——是时候掉头了。
在一个完美的动态世界中,它应该是“不”——但经过仔细检查,似乎没有区别(考虑到 JIT 魔法)或者它可能会稍微慢一些,尽管不足以保证不使用它(我当然是)。
理论上,如果正确实现,ViewBag 最终会胜过 ViewData 字典的使用,因为表达式的绑定(例如ViewBag.Foo
)在编译器将生成的不同CallSite中很好地缓存(反映了执行读取或写入的方法你会ViewBag
明白我的意思)。
DLR 的缓存层有据可查(如果深入了解后有点难以理解),但基本上运行时会尽力“记住”给定值实例一旦绑定它的位置 - 例如通过 Set 或得到声明。
但是缓存、它的使用和有效性完全取决于类/接口的底层实现,例如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 周期不会产生任何影响。人们可以在其他地方找到更大的性能改进。