렌더링 시간 및 성능 측면에서 패널은 어떤 순서로 가장 효율적입니까?


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 패널에 보이지 않는 내용의 양에 달려 있다고 생각합니다. 보이지 않는 항목이 VirtualizingStackPanel많으면 성능이 향상되지만 패널에 표시된 모든 항목이 표시되는 경우 일반 패널을 사용하는 것이 좋습니다.
Rachel

감사. 어쨌든 모든 항목이 표시 될 때 낭비 가상화 항목이 될 수 있습니다.
BoltClock

가상화 이외의 기능은 서로 다르거 나 별도의 컨트롤이 아닙니다. 고객에게 최고의 UI를 제공하는 것에 대해 설명합니다.
paparazzo

1
가상화 외에 눈에 띄는 차이가 있습니까? 그들이해야 할 일은 비교적 가벼운 레이아웃 알고리즘을 수행하는 것입니다. 뒤 따르는 모든 렌더링에 비해 작은. 그러나 그리드는 아마도 가장 느릴 것입니다 (가중 스케일링).
Henk Holterman

답변:


130

절대적인 상대 성능 비교를 제공하는 것보다 각 패널의 성능 특성을 설명하는 것이 더 간결하고 이해 가능하다고 생각합니다.

WPF는 내용을 렌더링 할 때 측정 및 정렬이라는 두 가지 패스를 만듭니다. 각 패널은이 두 패스 각각에 대해 서로 다른 성능 특성을 갖습니다.

측정 패스의 성능은 정렬을 사용하여 스트레칭을 수용 할 수있는 기능 (또는의 경우 자동 Grid)과 스트레칭 또는 자동 크기 조정 된 자식 수에 따라 패널의 성능이 가장 큰 영향을받습니다 . 배열 패스의 성능은 다른 어린이의 레이아웃 위치와 어린이 수의 상호 작용이 복잡하기 때문에 영향을받습니다.

때로는 주어진 패널이 필요한 레이아웃에 쉽게 적합하지 않습니다. 사용 가능한 공간의 특정 백분율에 각 항목을 배치하기 위해 임의의 수의 항목이 필요한 컨트롤을 만들었습니다. 기본 컨트롤 중 어느 것도이 작업을 수행하지 않습니다. 부모의 실제 크기에 바인딩하여이를 수행하려고하면 끔찍한 성능이 발생합니다. 캔버스를 기반으로 레이아웃 패널을 만들었으며 최소한의 작업으로 원하는 결과를 얻었습니다 (캔버스의 소스를 복사하고 약 20 줄을 수정했습니다).

사용 가능한 패널 :

  • 캔버스

    캔버스 영역을 기준으로 좌표로 자식 요소를 명시 적으로 배치 할 수있는 영역을 정의합니다.

    캔버스는 각 항목에 정적으로 위치가 지정되므로 정렬 패스에 대한 모든 패널의 성능이 가장 우수합니다. 이 패널에는 스트레칭 개념이 없기 때문에 측정 패스도 뛰어난 성능을 발휘합니다. 각 어린이는 단순히 기본 크기를 사용합니다.

  • DockPanel

    자식 요소를 서로에 대해 가로 또는 세로로 배열 할 수있는 영역을 정의합니다.

    Dockpanel에는 이전에 추가 한 항목을 기준으로 항목을 하나씩 추가하는 매우 간단한 레이아웃 구성표가 있습니다. 기본적으로 높이 또는 너비는 항목의 기본 크기 (각각 상단 / 하단 대 왼쪽 / 오른쪽 기준)에 의해 결정되며 다른 방향은 Dock너비 또는 높이가 정의되지 않은 경우 속성에 의해 결정됩니다 . 중간에서 빠른 측정 단계 및 중간에서 빠른 배열 단계.

  • 그리드

    열과 행으로 구성된 유연한 그리드 영역을 정의합니다.

    비례 크기 조정 또는 자동 크기 조정을 사용하는 경우 가장 성능 집약적 인 패널이 될 수 있습니다. 자식 항목 크기 계산은 항목의 기본 크기와 격자로 지정된 레이아웃의 복잡한 조합 일 수 있습니다. 레이아웃은 모든 패널 중에서 가장 복잡합니다. 측정 단계의 경우 중간에서 중간 성능, 정렬 단계의 경우 중간에서 느린 성능.

  • StackPanel

    자식 요소를 가로 또는 세로 방향으로 정렬 할 수있는 단일 선으로 정렬합니다.

    StackPanel은 방향과 반대 방향으로 기본 또는 상대 크기를 사용하고 방향 방향으로 기본 크기를 사용하여 자식을 측정합니다 (정렬은이 방향으로 아무것도 수행하지 않습니다). 이를 통해이 분야의 중급 기업이됩니다. 배열 패스는 단순히 항목을 순서대로 배치하는 것입니다. 이 패스에서 두 번째로 좋은 성능 일 것입니다. 측정 단계의 중간 성능 및 레이아웃 단계의 빠른 성능

  • 가상화 패널

    자식 데이터 수집을 가상화하는 패널 요소에 대한 프레임 워크를 제공합니다. 이것은 추상 클래스입니다.

    자체 가상화 패널을 구현하기위한 기본 클래스입니다. 메모리와 프로세서의 불필요한 사용을 방지하기 위해 보이는 항목 만로드합니다. 아이템 세트의 성능이 훨씬 뛰어납니다. 경계 확인으로 인해 화면에 맞는 항목의 성능이 약간 떨어질 수 있습니다. SDK는이 하위 클래스 중 하나만 제공합니다 VirtualizingStackPanel.

  • 랩 패널

    하위 요소를 왼쪽에서 오른쪽으로 순차적으로 배치하여 내용을 포함하는 상자 가장자리의 다음 줄로 나눕니다. 이후의 순서는 방향 속성 값에 따라 위에서 아래로 또는 오른쪽에서 왼쪽으로 순차적으로 발생합니다.

    측정 단계는 특정 행의 가장 큰 항목이 행의 높이를 결정한 다음 해당 행의 각 항목이 기본 높이 (있는 경우) 또는 행의 높이를 사용하는 다소 복잡한 패스입니다. 레이아웃 패스는 간단하여 각 항목을 하나씩 차례로 배치 한 다음 다음 항목을위한 공간이 충분하지 않으면 다음 행으로 계속 진행합니다. 중간 성능 측정 단계. 어레인지먼트 패스의 중간에서 빠른 성능.

참고 문헌 :

가능하면 가장 효율적인 패널을 사용하십시오

레이아웃 프로세스의 복잡성은 사용하는 패널 파생 요소의 레이아웃 동작을 직접 기반으로합니다. 예를 들어 Grid 또는 StackPanel 컨트롤은 Canvas 컨트롤보다 훨씬 더 많은 기능을 제공합니다. 이러한 기능 향상의 가격은 성능 비용의 증가입니다. 그러나 Grid 컨트롤이 제공하는 기능이 필요하지 않은 경우 Canvas 또는 사용자 정의 패널과 같이 비용이 저렴한 대안을 사용해야합니다.

에서 레이아웃 및 디자인 : 성능 최적화

레이아웃 시스템은 Children 컬렉션의 각 멤버에 대해 두 개의 패스, 소절 패스 및 어레인지 패스를 완료합니다. 각 하위 패널은 고유 한 레이아웃 동작을 달성하기 위해 자체 MeasureOverride 및 ArrangeOverride 메소드를 제공합니다.

측정 단계 동안 Children 컬렉션의 각 구성원이 평가됩니다. 프로세스는 Measure 메서드를 호출하는 것으로 시작합니다. 이 메서드는 부모 Panel 요소의 구현 내에서 호출되며 레이아웃이 발생하기 위해 명시 적으로 호출 할 필요는 없습니다.

먼저 UIElement의 기본 크기 속성 (예 : Clip 및 Visibility)이 평가됩니다. 그러면 MeasureCore로 전달되는 constraintSize라는 값이 생성됩니다.

둘째, FrameworkElement에 정의 된 프레임 워크 속성이 처리되어 constraintSize의 값에 영향을줍니다. 이러한 속성은 일반적으로 높이, 너비, 여백 및 스타일과 같은 기본 UIElement의 크기 특성을 설명합니다. 이러한 각 속성은 요소를 표시하는 데 필요한 공간을 변경할 수 있습니다. 그런 다음 constraintSize를 매개 변수로 사용하여 MeasureOverride가 호출됩니다.

참고 Height 및 Width 속성과 ActualHeight 및 ActualWidth 속성에는 차이가 있습니다. 예를 들어 ActualHeight 속성은 다른 높이 입력 및 레이아웃 시스템을 기반으로 계산 된 값입니다. 이 값은 실제 렌더링 패스를 기준으로 레이아웃 시스템 자체에 의해 설정되므로 입력 변경의 기초가되는 Height와 같은 속성의 설정 값보다 약간 뒤처 질 수 있습니다. ActualHeight는 계산 된 값이므로 레이아웃 시스템에 의한 다양한 작업의 결과로 여러 변경 또는 증분보고 된 변경 사항이있을 수 있습니다. 레이아웃 시스템은 자식 요소에 필요한 측정 공간, 부모 요소에 의한 제약 조건 등을 계산할 수 있습니다. 측정 단계의 궁극적 인 목표는 아동이 DesiredSize를 결정하는 것입니다. 이는 MeasureCore 호출 중에 발생합니다. DesiredSize 값은 콘텐츠 정렬 단계에서 사용하기 위해 Measure에 의해 저장됩니다.

정렬 단계는 Arrange 메서드를 호출하는 것으로 시작합니다. 정렬 단계 동안 부모 패널 요소는 자식의 경계를 나타내는 사각형을 생성합니다. 이 값은 처리를 위해 ArrangeCore 메소드로 전달됩니다.

ArrangeCore 메서드는 자식의 DesiredSize를 평가하고 요소의 렌더링 된 크기에 영향을 줄 수있는 추가 여백을 평가합니다. ArrangeCore는 배열의 ArrangeOverride 메소드에 매개 변수로 전달되는 배열 크기를 생성합니다. ArrangeOverride는 자식의 finalSize를 생성합니다. 마지막으로 ArrangeCore 메서드는 여백 및 정렬과 같은 오프셋 속성을 최종 평가하고 자식을 레이아웃 슬롯에 배치합니다. 자식은 할당 된 전체 공간을 채울 필요가 없으며 자주하지 않습니다. 그런 다음 컨트롤이 부모 패널로 돌아가고 레이아웃 프로세스가 완료됩니다.

에서 어린이를 측정 및 정렬


1
삭제 된 의견에 대한 답변 : 도움이되지 않기 때문에 통계를 포함하지 않았습니다. 스프레드 시트를 사용하기에는 조합이 너무 많습니다. 성능을 최적화하는 데 더 유용한 방법은 일반적인 이해를 사용하여 초기 레이아웃 패널을 선택한 다음 실제 상황을 분석하여 필요에 따라 최적화하는 것입니다.
N_A

WPF 패널이 실제로 렌더링되는 방식에 대한 설명과 각 패널의 측정 / 정렬 성능이 내가 요청한 것보다 훨씬 낫습니다.
Rachel

@mydogisbox 나는 UniformGrid당신의 목록에 어디에도 보이지 않습니다 . 해당 패널로 답변을 업데이트 할 수 있습니까? 다른 패널 유형과 관련하여 예상 측정 / 정렬 성능입니까?
Rachel

1
@Rachel UniformGrid응용 프로그램 레이아웃에 사용하기위한 것이 아닙니다. 자세한 내용은 "파생 패널 요소"( msdn.microsoft.com/en-us/library/ms754152.aspx) 를 참조하십시오. 속도는 a보다 약간 빠르며 a보다 DockPanel약간 느립니다 Canvas.
N_A

12

어쩌면 이것이 도움 될 것입니다.

패널뿐만 아니라 WPF에서 만들려는 모든 응용 프로그램에도 적용됩니다.

WPF 그리기 및 측정 성능을 마칩니다.

또한 대상으로 지정할 다른 운영 체제에 대한 그리기 테스트 응용 프로그램, 결과 및 결론 정보가 있습니다.


8

언급 한 패널은 레이아웃 패널이므로 레이아웃 시스템에 대한 간략한 개요는 가장 효율적인 패널의 단순한 목록이 아니라 효율성과 성능에 가장 큰 영향을 미치는 패널을 사용하는 방법을 제안합니다.

LayoutSystem_Overview :

가장 단순한 레이아웃은 요소의 크기, 위치 및 그리기를 유도하는 재귀 시스템입니다. 보다 구체적으로, 레이아웃은 Panel 요소의 Children 컬렉션 멤버를 측정하고 배열하는 프로세스를 설명합니다. 레이아웃은 집중적 인 프로세스입니다. Children 컬렉션이 클수록 계산 횟수가 많아집니다. 컬렉션을 소유 한 Panel 요소에 의해 정의 된 레이아웃 동작을 기반으로 복잡성을 도입 할 수도 있습니다. Canvas와 같은 비교적 간단한 Panel은 Grid와 같은 복잡한 패널보다 성능이 훨씬 뛰어납니다.

자식 UIElement가 위치를 변경할 때마다 레이아웃 시스템에서 새 패스를 트리거 할 가능성이 있습니다. 따라서 불필요한 호출은 응용 프로그램 성능을 저하시킬 수 있으므로 레이아웃 시스템을 호출 할 수있는 이벤트를 이해하는 것이 중요합니다. 다음은 레이아웃 시스템이 호출 될 때 발생하는 프로세스를 설명합니다.

1. 자식 UIElement는 먼저 핵심 속성을 측정하여 레이아웃 프로세스를 시작합니다.

2. FrameworkElement에 정의 된 크기 속성 (예 : 너비, 높이 및 여백)이 평가됩니다.

3. 독 방향 또는 스택 방향과 같은 패널 별 로직이 적용됩니다.

4. 모든 어린이가 측정 된 후에 내용이 배열됩니다.

5. 어린이 컬렉션이 화면에 그려집니다.

6. 컬렉션에 추가 자식이 추가되거나 LayoutTransform이 적용되거나 UpdateLayout 메서드가 호출되면 프로세스가 다시 호출됩니다.

자식 측정 및 배열에 대한 자세한 내용 은 LayoutSystem_Measure_Arrange 를 참조하십시오.

LayoutSystem_Performance :

레이아웃은 재귀 프로세스입니다. Children 컬렉션의 각 자식 요소는 레이아웃 시스템을 호출 할 때마다 처리됩니다. 결과적으로 레이아웃 시스템의 트리거는 필요하지 않을 때 피해야합니다. 다음 고려 사항은 성능을 향상시키는 데 도움이 될 수 있습니다.

레이아웃 시스템에서 어떤 속성 값을 변경하면 재귀 적으로 업데이트되는지 확인하십시오.

값으로 인해 레이아웃 시스템이 초기화 될 수있는 종속성 속성에는 공용 플래그가 표시됩니다. AffectsMeasure 및 AffectsArrange는 속성 값 변경이 레이아웃 시스템에 의해 재귀 적으로 업데이트되도록하는 유용한 단서를 제공합니다. 일반적으로 요소의 경계 상자 크기에 영향을 줄 수있는 속성에는 AffectsMeasure 플래그가 true로 설정되어 있어야합니다. 자세한 내용은 종속성 속성 개요를 참조하십시오.

가능하면 LayoutTransform 대신 RenderTransform을 사용하십시오.

LayoutTransform은 UI (사용자 인터페이스)의 내용에 영향을주는 매우 유용한 방법입니다. 그러나 변환 효과가 다른 요소의 위치에 영향을 미치지 않아도되는 경우 RenderTransform은 레이아웃 시스템을 호출하지 않으므로 RenderTransform을 대신 사용하는 것이 가장 좋습니다. LayoutTransform은 변형을 적용하고 영향을받는 요소의 새 위치를 설명하기 위해 재귀 적 레이아웃 업데이트를 강제합니다.

UpdateLayout에 대한 불필요한 호출을 피하십시오.

UpdateLayout 메서드는 재귀 적 레이아웃 업데이트를 강제 실행하므로 종종 필요하지 않습니다. 전체 업데이트가 필요한지 확실하지 않으면 레이아웃 시스템을 사용하여이 메소드를 호출하십시오.

대규모 Children 컬렉션으로 작업 할 때는 일반 StackPanel 대신 VirtualizingStackPanel을 사용하는 것이 좋습니다.

자식 컬렉션을 가상화함으로써 VirtualizingStackPanel은 현재 부모의 ViewPort 내에있는 메모리에만 개체를 ​​유지합니다. 결과적으로 대부분의 시나리오에서 성능이 크게 향상됩니다.

성능 최적화 : 레이아웃 및 디자인 :이 기사에서는 트리를 효율적으로 빌드하는 방법에 대해 자세히 설명하고 복잡도에 따라 간단한 패널 목록을 제공합니다.

캔버스 (최소 컴플렉스 : 더 효율적이고 더 나은 성능)

그리드

다른 패널

주의해야 할 다른 성능 고려 사항 : WPF UI 렌더링 속도를 향상시키는 방법

  1. 모든 것을 캐시하십시오. 브러쉬, 색상, 도형, 서식있는 텍스트, 글리프. (예를 들어, RenderTools와 TextCache의 두 클래스가 있습니다. 각 유닛의 렌더링 프로세스는 두 클래스의 공유 인스턴스로 주소 지정됩니다. 따라서 두 차트가 동일한 텍스트를 가진 경우 준비는 한 번만 실행됩니다.)
  2. 오랫동안 사용할 계획이라면 Freeze Freezable을 사용하십시오. 특히 기하학. 복잡한 동결되지 않은 형상은 HitTest를 매우 느리게 실행합니다.
  3. 각 프리미티브의 가장 빠른 렌더링 방법을 선택하십시오. 예를 들어 약 6 가지의 텍스트 렌더링 방법이 있지만 가장 빠른 방법은 DrawingContext.DrawGlyphs입니다.
  4. 컨테이너 재활용을 활성화합니다. 가상화는 많은 성능 향상을 가져 오지만 컨테이너는 폐기되고 다시 만들어집니다. 이것이 기본값입니다. 그러나 VirtualizingStackPanel.VirtualizationMode = "Recycling"을 설정하면 컨테이너를 재활용하여 더 많은 성능을 얻을 수 있습니다.
  5. 에서 여기 : 응용 프로그램이 지원할 수있는 중첩의 양에 실질적인 제한이 없습니다, 그러나, 실제로 원하는 레이아웃에 필요한 그 패널을 사용하려면 응용 프로그램을 제한하는 것이 가장 좋습니다. 많은 경우 레이아웃 컨테이너로서의 유연성으로 인해 중첩 패널 대신 그리드 요소를 사용할 수 있습니다. 이는 불필요한 요소를 트리 외부에 유지함으로써 응용 프로그램의 성능을 향상시킬 수 있습니다.

2
이 답변은 거의 전적으로 다른 출처에서 복사하여 붙여 넣기로 구성되며 일부는 속성이 없습니다. 관련 부분으로 만 다듬고 모든 출처를 올바르게 평가하고 질문에 더 직접 대답하려고하면 훨씬 좋습니다.
N_A

2
@mydogisbox 답변은 정보 모음이며, 답변에 사용한 것과 동일한 많은 사이트가 추가 될 수 있습니다. 성능 변경이라는 다른 측면을 고려하지 않으면 불완전한 답변으로 이어질 수도 있고 추가 질문이 여전히있을 수도 있으므로 질문을 포함하기로 결정했습니다. 놀라운 21.7K의 담당자와 많은 WPF 경험을 가진 Rachel은 이미이 정보를 알고 있을지 모르지만이 질문을보고있는 다른 사람들은이 추가적이고 반복적 인 정보와 함께 답을 원할 수 있습니다.
Erick
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.