ViewBag与MVC中的ViewData性能差异?

use*_*867 34 asp.net-mvc performance viewdata viewbag asp.net-mvc-3

我知道ViewData和ViewBag都使用相同的后备数据,并且在大多数情况下都不如使用强类型模型那样好.但是,在两者之间进行选择时,ViewBag的动态特性比使用ViewData慢吗?

And*_*tan 48

好的 - 我最初的回答基本上是'不' - 时间稍微过了一下.

在一个完美的动态世界中它应该是'不' - 但仔细观察后,似乎没有任何差别(占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;
}
Run Code Online (Sandbox Code Playgroud)

对于 var a = ViewBag.Foo

public override bool TrySetMember(SetMemberBinder binder, object value)
{
  this.ViewData[binder.Name] = value;
  return true;
}
Run Code Online (Sandbox Code Playgroud)

对于 ViewBag.Foo = Bar;

换句话说 - 语句被有效地重写为字典索引器周围的包装器.

因此,当然没有办法比自己动手更快.

如果用它ViewDataViewBag代替其他方式,ViewBag然后用类似的方式实现ExpandoObject,那么它可能是一个不同的故事 - 因为动态实现ExpandoObject更加智能,它采用的缓存规则允许一些漂亮很酷的运行时优化.

结论

(感谢Shawn McLean建议需要一个!)

ViewBag将比ViewData慢; 但可能不足以引起关注.

  • @Shawn Mclean - 大声笑,是的,你是对的!更新我的答案:) (4认同)
  • 你能不能...得出一个结论,像我这样懒惰的人只想知道哪个更好可以读到最后一段大声笑? (3认同)
  • 需要注意的是让我自己寻找这个问题的答案,VS2013显示了*在调试中尝试访问时出现Microsoft.CSharp.dll*错误的类型'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException'的第一次机会异常.无论这是仅在调试中发生还是通常作为流程的一部分,都需要考虑.ViewData不会抛出它.这是值存在的时候. (2认同)

Jak*_*cki 9

我没有做任何测试,但我的直觉是,在现实世界的场景中,差异可以忽略不计.您可能会在每个页面上访问几次,并且几个CPU周期不会有任何区别.人们可以在其他地方找到更大的性能改进.