Вопрос

Какая из следующих привязок TextBlocks требует большей производительности:

<Window  
  x:Name="Me"
  x:Class="MainWindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
  xmlns:src="clr-namespace:WpfApplication1" 
  Title="MainWindow">
  <StackPanel>
    <TextBlock Text="{Binding Title, ElementName=Me}"/>
    <TextBlock Text="{Binding Title, RelativeSource={RelativeSource AncestorType={x:Type src:MainWindow}}}"/>
  </StackPanel>    
</Window>

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

Соображения

(исходя исключительно из личных соображений, могу ошибаться в каждом конкретном случае!):

  • ElementName:

    • Можно искать и сравнивать текущий элемент для большего контроля над всеми его дочерними элементами, братьями и сестрами, дядями и двоюродными братьями, включая предков (может быть, существует HashTable всех зарегистрированных имен?)
    • Получение Name свойство элемента управления должно стоить меньше производительности, чем вызов GetType.
    • Сравнение строки обходится дешевле, чем сравнение типов, особенно если вы знаете, что большинство элементов управления даже не имеют своих Name набор.
  • FindAncestor:

    • Будет перебирать только предков, а не братьев и сестер, «дядей», «кузенов» и т. д.
    • Скорее всего использует GetType определить тип предка;GetType требует большей производительности, чем простой Name метод получения свойств (может быть, DP разные?)
Это было полезно?

Решение

Обычно это ужасная идея — пытаться ответить на подобные вопросы, споря о том, что, по вашему мнению, будет быстрее.Гораздо лучше построить эксперимент для его измерения.

Я немного изменил вашу настройку - я поместил соответствующий Xaml в UserControl и привязал его к Name собственность с тех пор UserControl не имеет Title свойство.Затем я написал код для создания нового экземпляра элемента управления и добавления его в пользовательский интерфейс, а также использовал метод Stopwatch для измерения времени, затраченного на его постройку и загрузку.(Я запускаю отсчет времени непосредственно перед созданием пользовательского элемента управления и прекращаю сразу после того, как пользовательский элемент управления поднимает Loaded событие.)

Я запускаю этот код из DispatcherTimer 20 раз в секунду, чтобы я мог проводить множество измерений в надежде уменьшить экспериментальную ошибку.Чтобы свести к минимуму искажения из-за отладочного и диагностического кода, я запускаю сборку Release и вычисляю и печатаю среднее значение только после завершения 2000 итераций.

После 2000 итераций ElementName подход составляет в среднем 887us.

После 2000 итераций RelativeSource подход составляет в среднем 959us.

Так ElementName в этом конкретном эксперименте немного быстрее, чем RelativeSource.Загрузка тривиальной UserControl всего лишь с Grid и один TextBlock где есть только один именованный элемент, ElementName Похоже, что на загрузку этого подхода уходит 92 % времени. RelativeSource подход требует.

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

Я повторил эксперимент с 10 TextBlocks вместо 1. ElementName затем составило в среднем 2020 г., в то время как RelativeSource В среднем подход составил 2073 мкс, то есть снова более 2000 итераций для обоих тестов.Как ни странно, здесь разница меньше, не только в относительном, но и в абсолютном выражении: примеры с одним элементом показали разницу в 72 мкс, тогда как примеры из десяти элементов показали разницу в 53 мкс.

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

Еще одна вариация:по-прежнему имея 10 связанных текстовых блоков, я добавил в пользовательский элемент управления еще десять пустых несвязанных текстовых блоков с именами.Идея заключалась в том, чтобы ввести больше именованных вещей - ElementName теперь ему нужно найти названный предмет среди 11 названных предметов.Среднее значение для ElementName сейчас 2775us.А RelativeSource подход с этими дополнительными 10 именованными элементами появился в 3041us.

Опять же, я подозреваю здесь изменчивость на моем настольном компьютере - кажется странным, что RelativeSource здесь результаты оказались значительно хуже, чем в сценарии, который должен был быть более ElementNameпреимущество.

В любом случае, что делает Кажется достаточно очевидным, что стоимость загрузки здесь гораздо более чувствительна к количеству элементов, чем к тому, какой стиль привязки вы используете.Видимо, есть небольшое преимущество ElementName но достаточно мал (и с достаточно странными результатами), чтобы вызвать подозрение в обоснованности вывода о том, что это обязательно быстрее.

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

Итак, в заключение:Производительность — это не тот предмет, на котором стоит здесь фокусироваться.Выбирайте тот, который делает код более читабельным.

Другие советы

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

Надеюсь, поможет,

Aj.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top