Разница в производительности ViewBag и ViewData в MVC?

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


person user169867    schedule 22.02.2011    source источник


Ответы (2)


Хорошо - мой первоначальный ответ в основном был отрицательным - пора сделать небольшой поворот.

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

Теоретически при правильной реализации ViewBag в конечном итоге превзойдет использование словаря ViewData, потому что привязка выражений (например, ViewBag.Foo) очень хорошо кэшируется в разных CallSite, которые компилятор сгенерирует (отражают метод, выполняющий чтение или запись в 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 был реализован даже с чем-то вроде _ 10_, тогда это может быть другая история - как динамическая реализация _ 11_ намного умнее, а правила кэширования, которые он использует, позволяют провести довольно крутые оптимизации времени выполнения.

В заключении

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

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

person Andras Zoltan    schedule 22.02.2011
comment
Не могли бы вы ... сделать вывод, чтобы ленивые люди вроде меня, которые просто хотят знать, что лучше, могут просто прочитать последний абзац, лол? - person Shawn Mclean; 27.04.2011
comment
@Shawn Mclean - лол, да, ты прав! Обновляю свой ответ :) - person Andras Zoltan; 27.04.2011
comment
Следует отметить, что заставило меня искать ответ на этот вопрос сам: VS2013 показывает ошибку Первое случайное исключение типа Microsoft.CSharp.RuntimeBinder.RuntimeBinderException в Microsoft.CSharp.dll при попытке для доступа к нему при отладке. Независимо от того, происходит ли это только при отладке или обычно как часть процесса, это следует учитывать. ViewData этого не бросает. Вот когда ценность действительно существует. - person Tony Basallo; 07.02.2015
comment
Да, это стандартная процедура для всего динамического кода, где динамическая реализация не находит член с заданным именем (за исключением типов, которые могут сами реализовывать динамический обмен через IDynamicMetaObjectProvider). И будет справедливо сказать, что это, безусловно, вносит свой вклад в разницу в скорости. - person Andras Zoltan; 10.02.2015

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

person Jakub Konecki    schedule 22.02.2011
comment
Согласен, это скорее академическое любопытство. - person user169867; 22.02.2011
comment
Единственное решение здесь - написать небольшой тест с for (i = 0; i ‹1000000; ++ i) - person Jakub Konecki; 22.02.2011
comment
@CallMeLaNN - испытание сложно сделать самому? - person Jakub Konecki; 07.03.2011
comment
Мне это легко, но сейчас я не ищу в этом серьезного выступления, если кто-то не потребует этого. Просто для информации, которую нужно учесть в будущем. Если я провожу тест прямо сейчас, а производительность для меня критична, я также хочу знать результаты других, поскольку они могут варьироваться в зависимости от алгоритма тестирования. - person CallMeLaNN; 12.03.2011