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

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

Например, MSDN заявляет, что

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

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

Панели WPF:

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

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

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

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

Обновить

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

  • Canvas
  • StackPanel
  • WrapPanel
  • DockPanel
  • Grid

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

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

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

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

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

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

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

  • canvas

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

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

  • DockPanel

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

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

  • grid

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

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

  • StackPanel

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

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

  • VirtualizingPanel

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

    Базовый class для реализации вашей собственной панели виртуализации. Загружает только видимые элементы, чтобы предотвратить ненужное использование памяти и процессора. БОЛЬШЕ более результативны для наборов предметов. Вероятно, немного менее эффективен для предметов, которые подходят на экране из-за проверки границ. SDK предоставляет только один подclass этого, VirtualizingStackPanel .

  • WrapPanel

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

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

Рекомендации:

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

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

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

Система компоновки завершает два прохода для каждого члена коллекции «Дети», пропуск за проезд и пропуск для организации. Каждая дочерняя панель предоставляет свои собственные методы MeasureOverride и ArrangeOverride для достижения своего собственного специфического поведения макета.

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

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

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

Примечание. Существует разница между свойствами Height и Width и ActualHeight и ActualWidth. Например, свойство ActualHeight является рассчитанным значением, основанным на других входах высоты и системе компоновки. Значение устанавливается самой системой компоновки, основанной на фактическом проходе рендеринга, и поэтому может немного отставать от установленного значения свойств, таких как Высота, которые являются основой изменения ввода. Поскольку ActualHeight является рассчитанным значением, вы должны знать, что в результате различных операций системой макета могут быть множественные или инкрементные сообщения об изменениях. Система макета может вычислять требуемое пространство измерения для дочерних элементов, ограничений родительским элементом и т. Д. Конечной целью прохождения меры является определение ребенком желаемого размера, которое происходит во время вызова MeasureCore. Значение DesiredSize хранится по методу измерения для использования во время прохождения аранжировки контента.

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

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

От измерения и организации детей

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

Он завершает работу по рисованию и измерению WPF.

Он также содержит информацию о приложении для тестирования, результатах и ​​выводах для разных операционных систем, для которых вы хотите настроить таргетинг.

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

LayoutSystem_Overview :

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

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

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

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

3. Используется специфичная для панели логика, такая как ориентация док-станции или ориентация штабелирования.

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

5. Коллекция детей рисуется на экране.

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

См. LayoutSystem_Measure_Arrange для получения дополнительной информации об измерении и организации детей

LayoutSystem_Performance :

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

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

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

Когда это возможно, используйте RenderTransform вместо LayoutTransform.

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

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

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

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

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

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

Холст (наименьшее дополнение = более эффективная и лучшая производительность)

grid

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

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

  1. Кэш все. Кисти, Цвета, Геометрия, Отформатированные Тексты, Символы. (Например, у нас есть два classа: RenderTools и TextCache. Процесс рендеринга каждого элемента адресуется к общему экземпляру обоих classов. Поэтому, если две диаграммы имеют один и тот же текст, его подготовка выполняется только один раз.)
  2. Freeze Freezable, если вы планируете использовать его в течение длительного времени. Особенно geometry. Сложные незамерзающие геометрии выполняют HitTest чрезвычайно медленно.
  3. Выберите самые быстрые способы рендеринга каждого примитива. Например, существует около 6 способов рендеринга текста, но самым быстрым является DrawingContext.DrawGlyphs.
  4. Включить переработку контейнеров. Виртуализация приносит много улучшений производительности, но контейнеры будут удалены и созданы повторно, это значение по умолчанию. Но вы можете получить больше производительности за счет контейнеров с переработкой, установив VirtualizingStackPanel.VirtualizationMode = “Recycling”
  5. Отсюда : практического ограничения количества вложений, поддерживаемых вашим приложением, как правило, лучше всего ограничить ваше приложение только теми панелями, которые действительно необходимы для вашего желаемого макета. Во многих случаях элемент Grid можно использовать вместо вложенных панелей из-за его гибкости в качестве контейнера компоновки. Это может повысить производительность вашего приложения, оставив ненужные элементы из дерева.
  • Является ли тернарный оператор быстрее, чем условие «если»
  • число n-й фибоначчи в сублинейном времени
  • Эффективный способ удаления строки из текстового файла
  • Конкатенация строк в C, какой метод более эффективен?
  • Кто-нибудь действительно эффективно реализовал Fibonacci-Heap?
  • Код C ++ для проверки гипотезы Collatz быстрее, чем assembly вручную - почему?
  • Каков наиболее эффективный способ проверки двух целых диапазонов для перекрытия?
  • Разделить большой фрейм данных в список фреймов данных на основе общего значения в столбце
  • Как профилировать использование памяти и производительность с помощью инструментов?
  • Соображения производительности для keySet () и entrySet () карты
  • MySQL загружает данные infile - ускорение?
  • Давайте будем гением компьютера.