Разница в производительности ViewBag и ViewData в MVC? - PullRequest
33 голосов
/ 22 февраля 2011

Я знаю, что и ViewData, и ViewBag используют одни и те же данные поддержки и что в большинстве случаев они не так хороши, как использование строго типизированных моделей. Однако при выборе между ними динамическая природа ViewBag медленнее, чем при использовании ViewData?

Ответы [ 2 ]

47 голосов
/ 22 февраля 2011

Хорошо, мой первоначальный ответ в основном сказал «нет» - время для разворота.

Это должно быть 'нет' в идеальном динамическом мире - но при ближайшем рассмотрении может показаться, что различий не будет (учитывая магию JIT), или может быть немного медленнее, хотя этого недостаточно, чтобы не использовать его (я, конечно, так).

Теоретически , если правильно реализовано , ViewBag в конечном итоге превзойдет использование словаря ViewData, потому что привязка выражений (например, ViewBag.Foo) очень хорошо кэшируется для различных CallSite s, которые сгенерирует компилятор (отразите метод, который выполняет чтение или запись в ViewBag, и вы поймете, что я имею в виду).

Кэширующие слои DLR хорошо документированы (если немного трудно понять, когда вы углубляетесь), но в основном среда выполнения делает все возможное, чтобы «запомнить», где данный экземпляр значения является его связать его - например, с помощью оператора Set или Get.

НО Кэширование, его использование и эффективность полностью зависят от базовых реализаций классов / интерфейсов, таких как 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 намного более интеллектуальна, а правила кэширования, которые она использует, допускают некоторые довольно крутые оптимизации во время выполнения.

В заключение

(спасибо Шону Маклину за предложение, что он нужен!)

ViewBag будет медленнее, чем ViewData; но, вероятно, недостаточно, чтобы оправдать беспокойство.

9 голосов
/ 22 февраля 2011

Я не проводил никаких тестов, но мое внутреннее чувство заключается в том, что в реальных сценариях разница просто незначительна.Вы, вероятно, получите доступ к нему несколько раз на каждой странице, и несколько циклов ЦП не будут иметь никакого значения.Можно найти большие улучшения производительности в других местах.

...