27 votes

Différence de performances entre ViewBag et ViewData dans MVC?

Je sais que ViewData et ViewBag utilisent tous deux les mêmes données de support et que ni l'un ni l'autre ne sont aussi bons que l'utilisation de modèles fortement typés dans la plupart des cas. Cependant, lorsque vous choisissez entre les deux, la nature dynamique de ViewBag est-elle plus lente que l'utilisation de ViewData?

39voto

Andras Zoltan Points 24996

Ok - ma première réponse est simplement dit " non " à temps pour un peu d'un demi-tour.

Il devrait être " non " dans un parfait dynamique du monde - mais regardant de plus près, il semblerait qu'il y aura soit pas de différence (comptabilité pour JIT magie) ou il pourrait être très légèrement plus lent, mais pas assez pour justifier de ne pas l'utiliser (je le suis).

En théorie , si elle est correctement mise en œuvre, le ViewBag serait, en définitive, de surperformer l'utilisation de la ViewData dictionnaire, parce que la liaison des expressions (par exemple, ViewBag.Foo) est très bien mis en cache à travers les différents CallSites que le compilateur va générer (refléter une méthode de lecture ou d'écriture à l' ViewBag et vous verrez ce que je veux dire).

La mise en cache des couches de la DLR sont bien documentés (même si un peu difficile à comprendre, une fois que vous obtenez en profondeur) mais au fond, l'exécution fait de son mieux pour "se souvenir" où une valeur donnée d'instance est une fois sa limite - par exemple par le biais d'un Ensemble ou d'Obtenir de l'énoncé.

MAIS La mise en cache, de son utilisation et de son efficacité, est entièrement dépendant de la implémentations sous-jacentes de classes/interfaces comme DynamicObject, idynamicmetaobjectprovider fournie par etc; ainsi que le résultat final de la Get/Set expression de liaison.

Dans le cas de la MVC interne DynamicViewDataDictionary de classe, au final, il finit par se liant à ceci:

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

Pour var a = ViewBag.Foo

Et

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

Pour ViewBag.Foo = Bar;

En d'autres termes, les états sont effectivement d'être réécrit pour wrappers autour du dictionnaire de l'indexeur.

À cause de cela, il n'y a certainement pas de la façon dont il pourrait être plus rapide que de le faire vous-même.

Ont été ViewData à se nourrir d' ViewBag, au lieu de l'inverse, et avait ViewBag alors été mis en œuvre avec même quelque chose comme ExpandoObject, alors il pourrait être une autre histoire - comme la dynamique de la mise en œuvre de l' ExpandoObject est beaucoup plus intelligente et la mise en cache des règles qu'il emploie permettre pour certains assez cool d'exécution des optimisations.

En Conclusion

(merci à Shawn McLean pour suggérant une a été nécessaire!)

ViewBag sera plus lente que ViewData; mais probablement pas assez pour justifier l'inquiétude.

7voto

Jakub Konecki Points 28852

Je n'ai fait aucun test, mais mon intuition est que dans des scénarios du monde réel, la différence est tout simplement négligeable. Vous y accéderez probablement plusieurs fois sur chaque page et quelques cycles CPU ne feront aucune différence. On peut trouver des améliorations de performances plus importantes dans d'autres endroits.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X