ViewBag vs ViewData performance difference in MVC?

25,217

Solution 1

Okay - my initial answer basically said 'no' - time for a bit of a u-turn.

It should be 'no' in a perfect dynamic world - but upon closer inspection it would appear that there will either be no difference (accounting for JIT magic) or it might be ever-so-slightly slower, although not enough to warrant not using it (I certainly am).

In theory if properly implemented, the ViewBag would ultimately outperform the use of the ViewData dictionary because the binding of the expressions (e.g. ViewBag.Foo) is very well cached across the different CallSites that the compiler will generate (reflect a method that does a read or write to the ViewBag and you'll see what I mean).

The caching layers of the DLR are well documented (if a little difficult to understand once you get in depth) but basically the runtime does its best to 'remember' where a given value instance is once its bound it - for example via a Set or Get statement.

BUT The caching, its use and effectiveness, is entirely dependent upon the underlying implementations of classes/interfaces such as DynamicObject, IDynamicMetaObjectProvider etc; as well as the end-result of the Get/Set expression binding.

In the case of the MVC internal DynamicViewDataDictionary class - it ultimately ends up binding to this:

public override bool TryGetMember(GetMemberBinder binder, out object result)
{
  result = this.ViewData[binder.Name];
  return true;
}

For var a = ViewBag.Foo

And

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

For ViewBag.Foo = Bar;

In other words - the statements are effectively being rewritten to wrappers around the dictionary indexer.

Because of that, there's certainly no way it could be faster than doing it yourself.

Were ViewData to feed off of ViewBag, instead of the other way around, and had ViewBag then been implemented with even something like ExpandoObject, then it might be a different story - as the dynamic implementation of ExpandoObject is much more intelligent and the caching rules it employs allow for some pretty cool runtime optimisations.

In Conclusion

(thanks to Shawn McLean for suggesting one was needed!)

ViewBag will be slower than ViewData; but probably not enough to warrant concern.

Solution 2

I haven't done any test but my gut feel is that in real world scenarios the difference is just negligible. You will probably access it a few times on each page and a few CPU cycles won't make any difference. One can find bigger performance improvements in other places.

Share:
25,217
user169867
Author by

user169867

Updated on July 09, 2022

Comments

  • user169867
    user169867 almost 2 years

    I know that ViewData and ViewBag both use the same backing data and that neither are as good as using strongly typed models in most cases. However when choosing between the two is the dynamic nature of ViewBag slower than using ViewData?

  • user169867
    user169867 about 13 years
    I agree, it's more of an academic curiosity.
  • Jakub Konecki
    Jakub Konecki about 13 years
    The only solution here is to write a little test with for(i=0; i<1000000; ++i)
  • Jakub Konecki
    Jakub Konecki about 13 years
    @CallMeLaNN - test to difficult for you to do yourself?
  • CallMeLaNN
    CallMeLaNN about 13 years
    I its easy but I am not looking for this right now as a serious performance unless someone claim it. Just for info to take into account in future development. If I do the test right now and performance is critical for me, I also want to know result from others since it may varies based on the test algorithm.
  • Shawn Mclean
    Shawn Mclean about 13 years
    Could you like...put a conclusion so lazy people like me who just wants to know which is better can just read the last paragraph lol?
  • Andras Zoltan
    Andras Zoltan about 13 years
    @Shawn Mclean - lol yeah you're right! Updating my answer :)
  • Tony Basallo
    Tony Basallo about 9 years
    Something to note that made me look for an answer to this question myself, VS2013 shows a A first chance exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in Microsoft.CSharp.dll error when trying to access it in debug. Whether this only happens in debug or normally as part of the process, it is something to consider. ViewData does not throw that. This is when the value does exist.
  • Andras Zoltan
    Andras Zoltan about 9 years
    Yup this is standard procedure for all dynamic code where the dynamic implementation does not find a member with the given name (outside of types which might implement the dynamic interchange themselves through IDynamicMetaObjectProvider) And it's fair to say that this contributes certainly part of the speed difference