В каком порядке панели наиболее эффективны с точки зрения времени рендеринга и производительности?


127

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

Например, MSDN утверждает, что

Относительно простой Panel, например Canvas, может иметь значительно лучшую производительность, чем более сложный Panel, например Grid.

Итак, с точки зрения времени рендеринга и производительности, в каком порядке панели WPF наиболее эффективны?

Панели WPF:

  • Canvas
  • DockPanel
  • Grid
  • UniformGrid
  • StackPanel
  • WrapPanel
  • VirtualizingPanel / VirtualizingStackPanel

Я почти уверен, что видел их список где-то в Интернете, но сейчас не могу его найти.

Идеальный ответ, который я ищу, предоставит мне список панелей в том порядке, в котором они будут отображаться быстрее всего. Я понимаю, что количество детей является важным фактором, влияющим на эффективность панелей, поэтому для ответа на этот вопрос предположим, что каждая панель имеет только пару Label/ TextBox.

Кроме того, мне нужен список исключений, таких как определенные панели, которые работают лучше других в зависимости от определенных условий.

Обновить

Подводя итог на основе принятого ниже ответа , производительность панели зависит от количества и расположения дочерних элементов, однако в целом список от самого быстрого к самому медленному:

  • Canvas
  • StackPanel
  • WrapPanel
  • DockPanel
  • Grid

Кроме того, VirtualizingPanel/ VirtualizingStackPanelвсегда следует использовать , если есть много вещей , которые не всегда помещаются на экране.

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


Наивно ли предполагать, что виртуализированные панели всегда будут работать лучше, чем невиртуализирующие панели?
BoltClock

@BoltClock Я думаю, это зависит от того, сколько невидимого контента на панели. Если есть много невидимых элементов, a VirtualizingStackPanelопределенно будет работать лучше, но если все элементы, отображаемые на панели, видны, я думаю, лучше использовать обычную панель.
Рэйчел

Спасибо. Совершенно очевидно, что виртуализация элементов будет пустой тратой, когда все они все равно будут отображаться.
BoltClock

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

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

Ответы:


130

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

WPF выполняет два прохода при рендеринге содержимого: измерение и упорядочение. Каждая панель имеет разные характеристики производительности для каждого из этих двух проходов.

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

Порой данные панели не легко поддаются нужной компоновке. Я создал элемент управления, которому требовалось произвольное количество элементов, каждый из которых должен располагаться на определенном проценте доступного пространства. Ни один из элементов управления по умолчанию этого не делает. Попытка заставить их сделать это (через привязку к фактическому размеру родителя) приводит к ужасной производительности. Я создал панель макета на основе Canvas, которая достигла желаемого результата с минимальными усилиями (я скопировал исходный код для холста и изменил его около 20 строк).

Доступные панели:

  • холст

    Определяет область, в которой вы можете явно позиционировать дочерние элементы по координатам относительно области Canvas.

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

  • DockPanel

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

    Dockpanel имеет очень простую схему компоновки, в которой элементы добавляются один за другим относительно предыдущего добавленного элемента. По умолчанию высота или ширина определяется собственным размером элемента (на основе верхнего / нижнего и левого / правого соответственно), а другое направление определяется Dockсвойством, если ширина или высота не определены. От среднего до быстрого прохода измерения и от среднего до быстрого прохода аранжировки.

  • сетка

    Определяет гибкую область сетки, состоящую из столбцов и строк.

    Это может быть панель с наиболее высокой производительностью, если используется пропорциональная калибровка или автоматическая калибровка. Расчет размера дочернего элемента может быть сложным сочетанием собственного размера элемента и макета, указанного в сетке. Планировка тоже самая сложная из всех панелей. От низкой до средней производительности для такта и от медленной до средней для аранжировки.

  • StackPanel

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

    StackPanel измеряет своих дочерних элементов, используя собственный или относительный размер в направлении, противоположном его ориентации, и собственный размер в направлении его ориентации (выравнивание ничего не делает в этом направлении). Это делает его исполнителем среднего уровня в этой области. Пропуск Arrangement - это просто размещение элементов по порядку. Наверное, второй лучший результат в этом пасе. Средняя производительность для прохода измерения и высокая производительность для прохода макета.

  • VirtualizingPanel

    Предоставляет основу для элементов Panel, которые виртуализируют их сбор дочерних данных. Это абстрактный класс.

    Базовый класс для реализации вашей собственной панели виртуализации. Загружает только видимые элементы, чтобы предотвратить ненужное использование памяти и процессора. НАМНОГО более производительный для наборов предметов. Вероятно, немного менее эффективен для элементов, которые помещаются на экране, из-за проверки границ. SDK предоставляет только один подкласс этого - VirtualizingStackPanel.

  • WrapPanel

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

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

Ссылки:

По возможности используйте наиболее эффективную панель

Сложность процесса компоновки напрямую зависит от поведения компоновки используемых вами элементов, производных от Panel. Например, элемент управления Grid или StackPanel предоставляет гораздо больше функциональных возможностей, чем элемент управления Canvas. Цена этого большего увеличения функциональности - большее увеличение затрат на производительность. Однако, если вам не требуются функциональные возможности, предоставляемые элементом управления Grid, следует использовать менее затратные альтернативы, такие как Canvas или настраиваемая панель.

От Оптимизация производительности: верстка и дизайн

Система макета выполняет два прохода для каждого члена коллекции Children, проход измерения и проход аранжировки. Каждая дочерняя Panel предоставляет свои собственные методы MeasureOverride и ArrangeOverride для достижения своего собственного поведения макета.

Во время передачи измерения оценивается каждый член коллекции Children. Процесс начинается с вызова метода Measure. Этот метод вызывается в реализации родительского элемента Panel, и его не нужно вызывать явно для создания макета.

Сначала оцениваются свойства собственного размера UIElement, такие как Clip и Visibility. Это генерирует значение с именем constraintSize, которое передается в MeasureCore.

Во-вторых, обрабатываются свойства платформы, определенные в FrameworkElement, что влияет на значение constraintSize. Эти свойства обычно описывают характеристики размера базового элемента UIElement, такие как его высота, ширина, поля и стиль. Каждое из этих свойств может изменять пространство, необходимое для отображения элемента. Затем вызывается MeasureOverride с параметром constraintSize.

Примечание. Существует разница между свойствами «Высота» и «Ширина», «Фактическая высота» и «Фактическая ширина». Например, свойство ActualHeight представляет собой вычисленное значение на основе других входных значений высоты и системы макета. Значение устанавливается самой системой макета на основе фактического прохода рендеринга и поэтому может немного отставать от установленного значения свойств, таких как Высота, которые являются основой изменения ввода. Поскольку ActualHeight является вычисляемым значением, вы должны знать, что в нем могут быть множественные или инкрементные сообщаемые изменения в результате различных операций системы макета. Система компоновки может вычислять необходимое пространство меры для дочерних элементов, ограничений родительского элемента и так далее. Конечная цель прохода измерения - определить для ребенка свой DesiredSize, который происходит во время вызова MeasureCore. Значение DesiredSize сохраняется в Measure для использования на этапе упорядочивания содержимого.

Этап аранжировки начинается с вызова метода Arrange. Во время этапа аранжировки родительский элемент Panel генерирует прямоугольник, представляющий границы дочернего элемента. Это значение передается в метод ArrangeCore для обработки.

Метод ArrangeCore оценивает DesiredSize дочернего элемента и оценивает любые дополнительные поля, которые могут повлиять на отображаемый размер элемента. ArrangeCore генерирует размер расположения, который передается методу ArrangeOverride панели в качестве параметра. ArrangeOverride генерирует finalSize дочернего элемента. Наконец, метод ArrangeCore выполняет окончательную оценку свойств смещения, таких как поля и выравнивание, и помещает дочерний элемент в слот макета. Ребенок не обязан (и часто не заполняет) все выделенное пространство. Затем управление возвращается родительской панели, и процесс макета завершается.

От измерения и расположения детей


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

Спасибо за ваше объяснение того, как на самом деле отображаются панели WPF, и производительность каждой панели Measure / Arrange намного лучше, чем то, о чем я просил :)
Рейчел

@mydogisbox Я нигде не вижу UniformGridв вашем списке. Сможете ли вы обновить свой ответ с помощью этой панели и ее оценки эффективности измерения / упорядочения по сравнению с другими типами панелей?
Рэйчел

1
@Rachel The UniformGridне предназначен для использования в макете приложения. См. «Производные элементы панели» здесь: msdn.microsoft.com/en-us/library/ms754152.aspx для получения дополнительной информации. По скорости он должен быть немного быстрее, чем a, DockPanelи немного медленнее, чем a Canvas.
N_A

12

Может это тебе поможет.

Не только для панелей, но и для каждого приложения, которое вы хотите создать в WPF.

Он завершает отрисовку и измерение производительности WPF.

В нем также есть приложение для рисования, результаты и выводы для различных операционных систем, на которые вы хотите ориентироваться.


8

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

LayoutSystem_Overview :

В простейшем случае макет - это рекурсивная система, которая приводит к изменению размера, расположению и рисованию элемента. В частности, макет описывает процесс измерения и упорядочивания членов коллекции Children элемента Panel. Верстка - это интенсивный процесс. Чем больше коллекция Children, тем большее количество вычислений необходимо выполнить. Сложность также может быть внесена на основе поведения макета, определенного элементом Panel, которому принадлежит коллекция. Относительно простая панель, такая как Canvas, может иметь значительно лучшую производительность, чем более сложная Panel, такая как Grid.

Каждый раз, когда дочерний элемент UIElement меняет свое положение, он может запустить новый проход системой макета. Следовательно, важно понимать события, которые могут вызывать систему макета, поскольку ненужный вызов может привести к снижению производительности приложения. Ниже описан процесс, который происходит при вызове системы макета.

1. Дочерний UIElement начинает процесс макета, сначала измеряя его основные свойства.

2. Оцениваются свойства размера, определенные в FrameworkElement, такие как ширина, высота и поля.

3. Применяется специфическая для панели логика, такая как направление стыковки или ориентация наложения.

4. Контент оформляется после того, как все дети были измерены.

5. На экране нарисована коллекция Children.

6. Процесс вызывается снова, если в коллекцию добавляются дополнительные дочерние элементы, применяется LayoutTransform или вызывается метод UpdateLayout.

См. LayoutSystem_Measure_Arrange для получения дополнительной информации об измерении и расположении дочерних элементов.

LayoutSystem_Performance :

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

Помните, какие изменения значений свойств вызовут рекурсивное обновление системой макета.

Свойства зависимостей, значения которых могут вызвать инициализацию системы макета, отмечены общедоступными флагами. AffectsMeasure и AffectsArrange предоставляют полезные подсказки относительно того, какие изменения значений свойств вызовут рекурсивное обновление системой макета. Как правило, для любого свойства, которое может влиять на размер ограничивающего прямоугольника элемента, для флага AffectsMeasure должно быть установлено значение true. Для получения дополнительной информации см. Обзор свойств зависимостей.

По возможности используйте RenderTransform вместо LayoutTransform.

LayoutTransform может быть очень полезным способом повлиять на содержимое пользовательского интерфейса (UI). Однако, если эффект преобразования не должен влиять на положение других элементов, лучше использовать вместо него RenderTransform, поскольку RenderTransform не вызывает систему макета. LayoutTransform применяет свое преобразование и заставляет рекурсивное обновление макета учитывать новое положение затронутого элемента.

Избегайте ненужных вызовов UpdateLayout.

Метод UpdateLayout вызывает рекурсивное обновление макета и часто в этом нет необходимости. Если вы не уверены, что требуется полное обновление, положитесь на систему макета, чтобы вызвать этот метод для вас.

При работе с большой дочерней коллекцией рассмотрите возможность использования VirtualizingStackPanel вместо обычной StackPanel.

Путем виртуализации дочерней коллекции VirtualizingStackPanel сохраняет в памяти только те объекты, которые в настоящее время находятся в родительском ViewPort. В результате в большинстве сценариев производительность существенно улучшается.

Оптимизация производительности: макет и дизайн : в этой статье подробно рассказывается о том, как эффективно построить дерево, и дается простой список панелей в зависимости от их сложности.

Canvas (наименее завершенный = более эффективный и производительный)

сетка

Другие панели (более сложные = менее эффективные и худшие)

Другие соображения производительности, на которые следует обратить внимание: Способы повышения скорости рендеринга пользовательского интерфейса WPF

  1. Кешируйте все. Кисти, цвета, геометрия, форматированные тексты, глифы. (Например, у нас есть два класса: RenderTools и TextCache. Процесс рендеринга каждого модуля обращается к общему экземпляру обоих классов. Поэтому, если две диаграммы имеют одинаковый текст, его подготовка выполняется только один раз.)
  2. Freeze Freezable, если вы планируете использовать его долгое время. Особенно геометрия. HitTest со сложной незамороженной геометрией выполняется очень медленно.
  3. Выбирайте самые быстрые способы рендеринга каждого примитива. Например, существует около 6 способов отрисовки текста, но самым быстрым является DrawingContext.DrawGlyphs.
  4. Включить переработку контейнеров. Виртуализация приносит много улучшений производительности, но контейнеры будут удалены и созданы заново, это значение по умолчанию. Но вы можете повысить производительность, повторно используя контейнеры, установив VirtualizingStackPanel.VirtualizationMode = "Recycling"
  5. От сюда : Там нет никакого практического ограничения на количество вложенности , что ваше приложение может поддерживать, однако, как правило , лучше всего ограничить ваше приложение использовать только те панели, которые действительно необходимы для нужного макета. Во многих случаях элемент сетки может использоваться вместо вложенных панелей из-за его гибкости в качестве контейнера макета. Это может повысить производительность вашего приложения за счет исключения ненужных элементов из дерева.

2
Этот ответ почти полностью состоит из копирования и вставки из других источников, некоторые из которых не указаны. Было бы намного лучше, если бы вы сократили его до только соответствующих частей, правильно атрибутировали все источники и попытались более прямо ответить на вопрос.
N_A

2
@mydogisbox Ответ - это сборник информации, я мог бы добавить, что многие из тех же сайтов, которые вы использовали в своем ответе. Чтобы не принимать во внимание другие аспекты, которые могут привести к неполному ответу или к тому, что у спрашивающего все еще есть дополнительные вопросы, изменение производительности может привести к тому, что я решил включить их. Хотя Рэйчел с потрясающей репутацией в 21,7 КБ и большим опытом работы с WPF, возможно, уже знает эту информацию, другие, которые смотрят на этот вопрос, могут захотеть получить эту дополнительную и важную информацию вместе с ответом.
Эрик
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.