В каком порядке панели наиболее эффективны с точки зрения времени рендеринга и производительности?
Много раз, когда более одной панели подходит для нужного макета, я знаю, что есть разница во времени рендеринга для разных типов панелей.
Например, MSDN утверждает, что
Относительно простой
Panel
, такие какCanvas
, может иметь значительно лучшую производительность, чем более сложныйPanel
, такие какGrid
,
Итак, с точки зрения времени рендеринга и производительности, в каком порядке панели WPF наиболее эффективны?
Панели WPF:
Canvas
DockPanel
Grid
UniformGrid
StackPanel
WrapPanel
VirtualizingPanel
/VirtualizingStackPanel
Я почти уверен, что видел список этого где-то в Интернете, но я не могу найти его сейчас.
Идеальный ответ, который я ищу, - предоставить мне список панелей в том порядке, в котором они отображаются быстрее. Я понимаю, что количество детей - это большой фактор эффективности панелей, поэтому ради этого вопроса предположим, что каждая панель имеет только Label
/TextBox
пара.
Кроме того, я хотел бы получить список исключений, таких как конкретные панели, которые работают лучше, чем другие, в зависимости от определенных условий.
Обновить
Подводя итоги, основываясь на принятом ответе ниже, производительность панели зависит от количества и расположения дочерних элементов, однако в целом список от самого быстрого до самого медленного:
Canvas
StackPanel
WrapPanel
DockPanel
Grid
Кроме того, VirtualizingPanel
/ VirtualizingStackPanel
всегда следует использовать, если на экране много предметов, которые не всегда умещаются.
Я настоятельно рекомендую вам прочитать принятый ответ ниже для получения более подробной информации, прежде чем просто выбрать элемент из этого списка.
3 ответа
Я думаю, что более кратко и понятно описать характеристики производительности каждой панели, чем пытаться дать абсолютное относительное сравнение производительности.
WPF делает два прохода при рендеринге контента: Measure и Arrange. Каждая панель имеет разные рабочие характеристики для каждого из этих двух проходов.
На эффективность прохода измерения больше всего влияет способность панели приспосабливаться к растяжению с помощью выравнивания (или Auto в случае Grid
), а затем количество детей, которые растянуты или авторазмера. На производительность прохода Arrange влияет сложность взаимодействия между расположением макета разных дочерних элементов и, конечно, количеством дочерних элементов.
Иногда данные панели не легко поддаются нужной компоновке. Я создал элемент управления, который требовал произвольного количества элементов, чтобы каждый из них располагался на определенном проценте доступного пространства. Ни один из элементов управления по умолчанию не делает этого. Попытка заставить их сделать это (посредством привязки к фактическому размеру родителя) приводит к ужасной производительности. Я создал панель макета на основе Canvas, которая достигла желаемого результата с минимальными затратами (я скопировал исходный текст для холста и изменил около 20 строк).
Доступные панели:
холст
Определяет область, в которой вы можете явно расположить дочерние элементы по координатам относительно области Canvas.
Холст имеет наилучшую производительность среди всех панелей для прохода аранжировки, поскольку каждому элементу статически назначается место. Проход измерения также имеет отличные характеристики, поскольку в этой панели нет концепции растяжения; каждый ребенок просто использует свой родной размер.
DockPanel
Определяет область, в которой вы можете расположить дочерние элементы по горизонтали или по вертикали относительно друг друга.
Dockpanel имеет очень простую схему компоновки, в которой элементы добавляются один за другим относительно предыдущего добавленного элемента. По умолчанию высота или ширина определяется собственным размером элемента (на основе сверху / снизу и слева / справа соответственно), а другое направление определяется
Dock
свойство, если ширина или высота не определены. Пропуск от среднего до быстрого и проход от среднего до быстрого.сетка
Определяет гибкую область сетки, которая состоит из столбцов и строк.
Это может быть панель с наибольшей производительностью, если используется пропорциональный или автоматический размер. Расчет размера дочернего элемента может представлять собой сложную комбинацию собственного размера элемента и макета, заданного сеткой. Расположение также является самым сложным из всех панелей. Производительность от медленной до средней для прохода меры и производительность от медленной до средней для прохода аранжировки.
StackPanel
Объединяет дочерние элементы в одну строку, которая может быть ориентирована горизонтально или вертикально.
StackPanel измеряет свои дочерние элементы, используя собственные или относительные размеры в противоположном направлении от своей ориентации и собственные размеры в направлении своей ориентации (выравнивание ничего не делает в этом направлении). Это делает его исполнителем среднего уровня в этой области. Пропуск Аранжировки это просто, просто выкладывая предметы по порядку. Вероятно, второе лучшее выступление для этого прохода. Средняя производительность для прохода измерения и высокая производительность для прохода макета.
VirtualizingPanel
Предоставляет платформу для элементов Panel, которые виртуализируют их дочерний сбор данных. Это абстрактный класс.
Базовый класс для реализации вашей собственной панели виртуализации. Загружает только видимые элементы, чтобы предотвратить ненужное использование памяти и процессора. НАМНОГО более производительный для наборов предметов. Вероятно, немного менее производительный для элементов, которые помещаются на экране из-за проверки границ. SDK предоставляет только один подкласс этого,
VirtualizingStackPanel
,WrapPanel
Позиционирует дочерние элементы в последовательном положении слева направо, разбивая содержимое на следующую строку на краю вмещающего блока. Последующее упорядочение происходит последовательно сверху вниз или справа налево, в зависимости от значения свойства Orientation.
Проход меры представляет собой довольно сложный проход, в котором самый большой элемент для конкретной строки определяет высоту строки, а затем каждый элемент в этой строке либо использует свою собственную высоту (если она есть), либо высоту строки. Этап макета прост: размещение каждого элемента один за другим в ряду, а затем переход к следующему ряду, когда для следующего элемента недостаточно места. Мера средней производительности пройти. Средняя и высокая производительность для прохода аранжировки.
Рекомендации:
Используйте наиболее эффективную панель, где это возможно
Сложность процесса макета напрямую зависит от поведения макета используемых вами производных от Panel элементов. Например, элемент управления Grid или StackPanel предоставляет гораздо больше функциональных возможностей, чем элемент управления Canvas. Ценой такого увеличения функциональности является увеличение затрат на производительность. Однако, если вам не требуются функции, предоставляемые элементом управления Grid, следует использовать менее дорогостоящие альтернативы, такие как Canvas или пользовательская панель.
От оптимизации производительности: макет и дизайн
Система макетов выполняет два прохода для каждого члена коллекции Children, проход для измерения и проход для аранжировки. Каждая дочерняя панель имеет свои собственные методы MeasureOverride и ArrangeOverride для достижения своего собственного поведения макета.
Во время прохождения мероприятия оценивается каждый член коллекции Children. Процесс начинается с вызова метода Measure. Этот метод вызывается в реализации родительского элемента Panel, и его не нужно явно вызывать для создания макета.
Сначала оцениваются свойства собственного размера UIElement, такие как Clip и Visibility. Это генерирует значение с именем constraintSize, которое передается в MeasureCore.
Во-вторых, обрабатываются свойства платформы, определенные в FrameworkElement, что влияет на значение constraintSize. Эти свойства обычно описывают характеристики размеров базового элемента UIElement, такие как его высота, ширина, поля и стиль. Каждое из этих свойств может изменить пространство, необходимое для отображения элемента. Затем вызывается метод MeasureOverride, в котором в качестве параметра используется constraintSize.
Примечание. Существуют различия между свойствами высоты и ширины, а также ActualHeight и ActualWidth. Например, свойство ActualHeight является вычисленным значением, основанным на других параметрах высоты и системе макетов. Значение задается самой системой макетов на основе фактического прохода рендеринга и поэтому может немного отставать от заданного значения свойств, таких как Высота, которые являются основой изменения ввода. Поскольку ActualHeight является вычисленным значением, вы должны знать, что в него могут быть внесены множественные или инкрементные изменения в результате различных операций системы макетов. Система макета может вычислять требуемое пространство измерения для дочерних элементов, ограничения родительским элементом и так далее. Конечная цель прохода меры - дать ребенку возможность определить его DesiredSize, который происходит во время вызова MeasureCore. Значение DesiredSize хранится в Measure для использования во время передачи содержимого.
Проход аранжировки начинается с вызова метода аранжировки. Во время прохода аранжировки родительский элемент Panel создает прямоугольник, представляющий границы дочернего элемента. Это значение передается в метод ArrangeCore для обработки.
Метод ArrangeCore оценивает DesiredSize дочернего элемента и оценивает любые дополнительные поля, которые могут повлиять на размер элемента, который отображается. ArrangeCore генерирует rangeSize, который передается методу ArrangeOverride Panel в качестве параметра. ArrangeOverride генерирует finalSize дочернего элемента. Наконец, метод ArrangeCore выполняет окончательную оценку свойств смещения, таких как поле и выравнивание, и помещает дочерний элемент в свой слот макета. Ребенок не должен (и часто не делает) заполнять все выделенное пространство. Затем элемент управления возвращается в родительскую панель, и процесс верстки завершен.
Может быть, это поможет вам.
Не только для панелей, но и для любого приложения, которое вы хотите сделать в WPF.
Это завершает WPF рисунок и измерения производительности.
Он также содержит приложение для тестирования чертежей, результаты и выводы для различных операционных систем, на которые вы хотите ориентироваться.
Упомянутые вами панели являются панелями макетов, поэтому краткий обзор системы макетов показывает, что, скорее всего, это будет не просто список наиболее эффективных панелей, а то, как вы используете панели, которые оказывают наибольшее влияние на эффективность и производительность.
В простейшем случае макет представляет собой рекурсивную систему, которая приводит к размеру, позиционированию и отрисовке элемента. Более конкретно, макет описывает процесс измерения и упорядочения элементов коллекции Children элемента Panel. Макет является интенсивным процессом. Чем больше коллекция Children, тем больше должно быть выполнено вычислений. Сложность также может быть введена на основе поведения макета, определенного элементом Panel, который владеет коллекцией. Относительно простая панель, такая как Canvas, может иметь значительно лучшую производительность, чем более сложная панель, такая как Grid.
Каждый раз, когда дочерний элемент UIElement меняет свою позицию, он может инициировать новый проход с помощью системы макетов. Поэтому важно понимать события, которые могут вызвать систему макетов, поскольку ненужный вызов может привести к снижению производительности приложения. Далее описывается процесс, который происходит при вызове системы макетов.
1. Дочерний UIElement начинает процесс компоновки, сначала измеряя его основные свойства.
2. Оцениваются свойства размеров, определенные в FrameworkElement, такие как Width, Height и Margin.
3. Применяется логика, специфичная для панели, например, направление дока или ориентация стека.
4. Содержание организовано после того, как все дети были измерены.
5. Детская коллекция нарисована на экране.
6. Процесс вызывается снова, если в коллекцию добавляются дополнительные дочерние элементы, применяется LayoutTransform или вызывается метод UpdateLayout.
Посмотрите LayoutSystem_Measure_Arrange для получения дополнительной информации об измерении и расположении детей
Макет является рекурсивным процессом. Каждый дочерний элемент в коллекции Children обрабатывается во время каждого вызова системы макета. В результате следует избегать запуска системы макетов, когда в этом нет необходимости. Следующие соображения могут помочь вам достичь лучшей производительности.
Помните, какие изменения значений свойств приведут к рекурсивному обновлению системой макетов.
Свойства зависимостей, значения которых могут привести к инициализации системы макетов, помечаются открытыми флагами. AffectsMeasure и AffectsArrange предоставляют полезные подсказки относительно того, какие изменения значений свойств приведут к рекурсивному обновлению системой макетов. В общем, любое свойство, которое может влиять на размер ограничивающего прямоугольника элемента, должно иметь для флага AffectsMeasure значение true. Для получения дополнительной информации см. Обзор свойств зависимости.
По возможности используйте RenderTransform вместо LayoutTransform.
LayoutTransform может быть очень полезным способом повлиять на содержимое пользовательского интерфейса (UI). Однако, если эффект преобразования не должен влиять на положение других элементов, лучше вместо этого использовать RenderTransform, поскольку RenderTransform не вызывает систему макетов. LayoutTransform применяет свое преобразование и вынуждает рекурсивное обновление макета учесть новую позицию затронутого элемента.
Избегайте ненужных звонков в UpdateLayout.
Метод UpdateLayout вызывает рекурсивное обновление макета и часто не требуется. Если вы не уверены, что требуется полное обновление, положитесь на систему макетов, чтобы вызвать этот метод для вас.
При работе с большой коллекцией Children рассмотрите возможность использования VirtualizingStackPanel вместо обычной StackPanel.
Виртуализируя дочернюю коллекцию, VirtualizingStackPanel сохраняет в памяти только те объекты, которые в данный момент находятся в родительском ViewPort. В результате производительность значительно улучшается в большинстве сценариев.
Оптимизация производительности: макет и дизайн. В этой статье подробно рассказывается о том, как эффективно построить дерево, и приводится простой список панелей в зависимости от их сложности.
Холст (наименьший завершенность = более эффективный и лучший результат)
сетка
Другие панели (более сложные = менее эффективные и худшие показатели)
Другие соображения производительности, на которые следует обратить внимание: способы повышения скорости рендеринга пользовательского интерфейса WPF
- Кэшируйте все. Кисти, цвета, геометрия, форматированные тексты, глифы. (Например, у нас есть два класса: RenderTools и TextCache. Процесс рендеринга каждого модуля обращается к общему экземпляру обоих классов. Поэтому, если две диаграммы имеют одинаковый текст, его подготовка выполняется только один раз.)
- Freeze Freezable, если вы планируете использовать его в течение длительного времени. Особенно геометрии. Сложные незамерзающие геометрии выполняют HitTest крайне медленно.
- Выберите самые быстрые способы рендеринга каждого примитива. Например, существует около 6 способов визуализации текста, но самым быстрым является DrawingContext.DrawGlyphs.
- Включить утилизацию контейнеров. Виртуализация приносит много улучшений производительности, но контейнеры будут удалены и созданы заново, это значение по умолчанию. Но вы можете повысить производительность, перерабатывая контейнеры, установив VirtualizingStackPanel.VirtualizationMode="Recycling"
- Отсюда: нет практического ограничения на количество вложений, которое может поддерживать ваше приложение, однако, как правило, лучше ограничить ваше приложение только теми панелями, которые действительно необходимы для вашего желаемого макета. Во многих случаях элемент Grid может использоваться вместо вложенных панелей благодаря его гибкости в качестве контейнера макета. Это может повысить производительность вашего приложения, убрав ненужные элементы из дерева.