W jakiej kolejności panele są najbardziej wydajne pod względem czasu renderowania i wydajności?


127

Często zdarza się, że więcej niż jeden panel pasuje do układu, który chcę, jednak wiem, że istnieje różnica w czasie renderowania dla różnych typów paneli.

Na przykład MSDN stwierdza, że

Stosunkowo prosty Panel, taki jak Canvas, może mieć znacznie lepszą wydajność niż bardziej złożony Panel, taki jak Grid.

Więc pod względem czasu renderowania i wydajności, w jakiej kolejności panele WPF są najbardziej wydajne?

Panele WPF:

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

Jestem prawie pewien, że widziałem listę tego gdzieś w Internecie, ale nie mogę jej teraz znaleźć.

Idealna odpowiedź, której szukam, to lista paneli w kolejności, w której renderowałyby się najszybciej. Rozumiem, że liczba dzieci ma duży wpływ na skuteczność paneli, więc na potrzeby tego pytania załóżmy, że każdy panel ma tylko parę Label/ TextBox.

Ponadto chciałbym uzyskać listę wyjątków, takich jak określone panele, które działają lepiej niż inne w oparciu o określone warunki.

Aktualizacja

Podsumowując na podstawie zaakceptowanej odpowiedzi poniżej, wydajność panelu jest oparta na liczbie i układzie elementów podrzędnych, jednak generalnie lista od najszybszych do najwolniejszych jest następująca:

  • Canvas
  • StackPanel
  • WrapPanel
  • DockPanel
  • Grid

Ponadto znak VirtualizingPanel/ VirtualizingStackPanelpowinien być zawsze używany, jeśli istnieje wiele elementów, które nie zawsze mieszczą się na ekranie.

Gorąco polecam przeczytanie zaakceptowanej odpowiedzi poniżej, aby uzyskać więcej informacji, zanim wybierzesz przedmiot z tej listy.


Czy naiwnym jest zakładanie, że wirtualizujące panele niezmiennie będą działać lepiej niż panele bez wirtualizacji?
BoltClock

@BoltClock Myślę, że to zależy od tego, ile niewidocznych treści znajduje się w panelu. Jeśli jest dużo niewidocznych elementów, VirtualizingStackPanelzdecydowanie lepiej się sprawdzi, ale jeśli wszystkie elementy wyświetlane w panelu są widoczne niż myślę, lepiej użyć zwykłego panelu.
Rachel

Dzięki. To ma sens, że byłoby to marnotrawstwem wirtualizacji elementów, skoro i tak wszystkie z nich zostaną wyświetlone.
BoltClock

Poza wirtualizacją mają inne funkcje lub nie byłyby oddzielnymi kontrolkami. Idę z tym, co zapewnia klientowi najlepszy interfejs użytkownika.
paparazzo

1
Czy na pewno istnieje zauważalna różnica (poza wirtualizacją)? Wszystko, co muszą zrobić, to wykonać stosunkowo lekki algorytm układu. Malutki w porównaniu do wszystkich renderingów, które będą później. Mimo to Siatka będzie prawdopodobnie najwolniejsza (skalowanie ważone).
Henk Holterman

Odpowiedzi:


130

Myślę, że opisanie charakterystyk wydajności każdego panelu jest bardziej zwięzłe i zrozumiałe niż próba uzyskania bezwzględnego względnego porównania wydajności.

WPF wykonuje dwa przebiegi podczas renderowania zawartości: Zmierz i Rozmieść. Każdy panel ma inną charakterystykę działania dla każdego z tych dwóch przejść.

Na wydajność przebiegu pomiaru największy wpływ ma zdolność panelu do dostosowania się do rozciągania za pomocą wyrównania (lub Auto w przypadku Grid), a następnie liczba elementów podrzędnych, które są rozciągane lub automatycznie dopasowują się do rozmiaru. Na wykonanie przebiegu Arrange ma wpływ złożoność interakcji między rozmieszczeniem różnych elementów potomnych, a następnie oczywiście liczbą elementów podrzędnych.

Czasami dane panele nie dają się łatwo dopasować do wymaganego układu. Utworzyłem kontrolkę, która wymagała dowolnej liczby elementów, aby każdy z nich był umieszczony w określonym procencie dostępnej przestrzeni. Żadna z domyślnych kontrolek tego nie robi. Próba zmuszenia ich do tego (poprzez powiązanie z rzeczywistym rozmiarem rodzica) skutkuje okropnymi wynikami. Stworzyłem panel układu w oparciu o Canvas, który przy minimalnym nakładzie pracy osiągnął pożądany efekt (skopiowałem źródło płótna i zmodyfikowałem około 20 linii).

Dostępne panele:

  • Brezentowy

    Definiuje obszar, w którym można jawnie umieszczać elementy podrzędne za pomocą współrzędnych względem obszaru Canvas.

    Płótno ma najlepszą wydajność wszystkich paneli dla przejścia aranżacji, ponieważ każdemu elementowi jest statycznie przypisana lokalizacja. Przejście pomiarowe ma również doskonałą wydajność, ponieważ w tym panelu nie ma koncepcji rozciągania; każde dziecko po prostu używa swojego natywnego rozmiaru.

  • DockPanel

    Definiuje obszar, w którym można rozmieścić elementy podrzędne poziomo lub pionowo względem siebie.

    Dockpanel ma bardzo prosty schemat układu, w którym elementy są dodawane jeden po drugim względem poprzedniego dodanego elementu. Domyślnie wysokość lub szerokość jest określana przez rodzimy rozmiar elementu (odpowiednio na podstawie góry / dołu i lewej / prawej strony), a inny kierunek jest określany przez Dockwłaściwość, jeśli szerokość lub wysokość są niezdefiniowane. Średni do szybkiego podania miary i średni do szybkiego przejścia aranżacyjnego.

  • Krata

    Definiuje elastyczny obszar siatki, który składa się z kolumn i wierszy.

    Może to być panel wymagający największej wydajności, jeśli używane jest skalowanie proporcjonalne lub automatyczne. Obliczanie rozmiaru elementu podrzędnego może być złożoną kombinacją natywnego rozmiaru elementu i układu określonego w siatce. Układ jest również najbardziej skomplikowany ze wszystkich paneli. Niska do średniej wydajności w przypadku przebiegu taktu i powolna do średniej wydajności w trakcie aranżacji.

  • StackPanel

    Układa elementy podrzędne w jednej linii, która może być zorientowana poziomo lub pionowo.

    StackPanel mierzy swoje elementy podrzędne przy użyciu rozmiaru natywnego lub względnego w kierunku przeciwnym do jego orientacji i rozmiaru natywnego w kierunku jego orientacji (wyrównanie nie robi nic w tym kierunku). To czyni go wykonawcą średniego poziomu w tej dziedzinie. Przepustka aranżacyjna to po prostu układanie elementów w kolejności. Prawdopodobnie drugi najlepszy wynik dla tej przepustki. Średnia wydajność dla przebiegu pomiaru i wysoka wydajność dla przebiegu układu.

  • VirtualizingPanel

    Zapewnia strukturę dla elementów panelu, które wirtualizują zbieranie danych podrzędnych. To jest klasa abstrakcyjna.

    Klasa bazowa do implementacji własnego panelu wirtualizacyjnego. Ładuje tylko widoczne elementy, aby zapobiec niepotrzebnemu użyciu pamięci i procesora. DUŻO bardziej wydajne dla zestawów przedmiotów. Prawdopodobnie nieco mniej wydajne w przypadku przedmiotów, które mieszczą się na ekranie ze względu na sprawdzanie granic. Zestaw SDK udostępnia tylko jedną podklasę tego programu VirtualizingStackPanel.

  • WrapPanel

    Ustawia elementy potomne w kolejności od lewej do prawej, przenosząc zawartość do następnego wiersza na krawędzi pola zawierającego. Kolejne porządkowanie odbywa się sekwencyjnie od góry do dołu lub od prawej do lewej, w zależności od wartości właściwości Orientation.

    Przebieg miary jest dość złożonym przebiegiem, w którym największy element w danym wierszu określa wysokość wiersza, a następnie każdy element w tym wierszu używa swojej natywnej wysokości (jeśli ma) lub wysokości wiersza. Przebieg układu jest prosty: umieszcza każdy element jeden po drugim w rzędzie, a następnie przechodzi do następnego rzędu, gdy nie ma wystarczającej ilości miejsca na następny element. Wynik pomiaru średniej wydajności. Średni do szybkiego wykonania dla przejścia aranżacyjnego.

Bibliografia:

Tam, gdzie to możliwe, używaj najbardziej wydajnego panelu

Złożoność procesu tworzenia układu jest bezpośrednio związana z zachowaniem układu elementów pochodnych panelu, których używasz. Na przykład kontrolka Grid lub StackPanel zapewnia znacznie więcej funkcji niż kontrolka Canvas. Ceną za ten większy wzrost funkcjonalności jest większy wzrost kosztów wydajności. Jeśli jednak nie potrzebujesz funkcji zapewnianej przez formant Grid, powinieneś użyć mniej kosztownych alternatyw, takich jak Canvas lub panel niestandardowy.

Od optymalizacji wydajności: układ i projekt

System layoutu uzupełnia dwie przepustki dla każdego członka kolekcji Children, przepustkę na miarę i przepustkę aranżacyjną. Każdy panel podrzędny udostępnia własne metody MeasureOverride i ArrangeOverride w celu uzyskania własnego określonego zachowania układu.

Podczas przepustki oceniany jest każdy członek kolekcji Children. Proces rozpoczyna się wywołaniem metody Measure. Ta metoda jest wywoływana w ramach implementacji elementu nadrzędnego Panel i nie musi być wywoływana jawnie, aby wystąpił układ.

Najpierw oceniane są właściwości rozmiaru natywnego elementu UIElement, takie jak klip i widoczność. Spowoduje to wygenerowanie wartości o nazwie constraintSize, która jest przesyłana do MeasureCore.

Po drugie, przetwarzane są właściwości struktury zdefiniowane w FrameworkElement, co wpływa na wartość constraintSize. Te właściwości ogólnie opisują charakterystykę ustalania rozmiaru bazowego elementu UIElement, na przykład wysokość, szerokość, margines i styl. Każda z tych właściwości może zmienić przestrzeń niezbędną do wyświetlenia elementu. MeasureOverride jest następnie wywoływana z constraintSize jako parametrem.

Uwaga Istnieje różnica między właściwościami Height i Width oraz ActualHeight i ActualWidth. Na przykład właściwość ActualHeight jest wartością obliczoną na podstawie innych danych wejściowych dotyczących wysokości i systemu układu. Wartość jest ustawiana przez sam system układu na podstawie rzeczywistego przebiegu renderowania i dlatego może pozostawać nieco w tyle za ustawioną wartością właściwości, takich jak wysokość, które są podstawą zmiany danych wejściowych. Ponieważ ActualHeight jest wartością obliczoną, należy mieć świadomość, że mogą wystąpić wielokrotne lub przyrostowe zgłaszane zmiany w wyniku różnych operacji wykonywanych przez system układu. System układu może obliczać wymaganą przestrzeń pomiarową dla elementów podrzędnych, ograniczeń elementu nadrzędnego i tak dalej. Ostatecznym celem podania miary jest określenie przez dziecko jego DesiredSize, która występuje podczas wywołania MeasureCore. Wartość DesiredSize jest przechowywana przez Measure do użycia podczas przebiegu porządkowania zawartości.

Przebieg aranżacji zaczyna się od wywołania metody Arrange. Podczas przebiegu aranżacji element nadrzędny Panel generuje prostokąt, który reprezentuje granice elementu podrzędnego. Ta wartość jest przenoszona do metody ArrangeCore w celu przetworzenia.

Metoda ArrangeCore szacuje DesiredSize elementu podrzędnego i oblicza wszelkie dodatkowe marginesy, które mogą mieć wpływ na renderowany rozmiar elementu. ArrangeCore generuje ArrangeSize, który jest przesyłany do metody ArrangeOverride Panel jako parametr. ArrangeOverride generuje finalSize elementu podrzędnego. Na koniec metoda ArrangeCore przeprowadza ostateczną ocenę właściwości przesunięcia, takich jak margines i wyrównanie, i umieszcza element podrzędny w swoim miejscu układu. Dziecko nie musi (a często nie wypełnia) całej przydzielonej przestrzeni. Następnie kontrola jest zwracana do panelu nadrzędnego i proces tworzenia układu jest zakończony.

Od mierzenia i organizowania dzieci


1
W odpowiedzi na usunięty komentarz: nie uwzględniłem wskaźników, ponieważ nie byłyby pomocne. Jest zbyt wiele kombinacji, aby arkusz kalkulacyjny był przydatny. Bardziej użyteczną metodą optymalizacji wydajności byłoby skorzystanie z ogólnej wiedzy w celu wybrania paneli układu początkowego, a następnie optymalizacja w razie potrzeby z wykorzystaniem analizy rzeczywistej sytuacji.
N_A

Dziękuję, wyjaśnienie, w jaki sposób panele WPF są renderowane, a wydajność pomiaru / aranżacji każdego panelu jest znacznie lepsza niż to, o co prosiłem :)
Rachel

@mydogisbox Nie widzę UniformGridnigdzie na twojej liście. Czy byłbyś w stanie zaktualizować swoją odpowiedź za pomocą tego panelu i jego szacunkowej wydajności pomiaru / aranżacji w odniesieniu do innych typów paneli?
Rachel

1
@Rachel The UniformGridnie jest przeznaczony do wykorzystania w układzie aplikacji. Aby uzyskać więcej informacji, zobacz „Pochodne elementy panelu” tutaj: msdn.microsoft.com/en-us/library/ms754152.aspx . Pod względem szybkości powinien być nieco szybszy niż a DockPaneli nieco wolniejszy niż a Canvas.
N_A

12

Może to ci pomoże.

Nie tylko do paneli, ale także do każdej aplikacji, którą chcesz wykonać w WPF.

Kończy rysowanie i pomiary wydajności WPF.

Zawiera również aplikację do testowania rysunków, wyniki i wnioski dla różnych systemów operacyjnych, na które chcesz kierować.


8

Panele, o których wspomniałeś, to panele układu, więc krótki przegląd systemu układu sugeruje, że prawdopodobnie nie będzie to tylko prosta lista najbardziej wydajnych paneli, ale sposób korzystania z paneli, które mają największy wpływ na wydajność i wydajność.

LayoutSystem_Overview :

Mówiąc najprościej, układ jest systemem rekurencyjnym, który prowadzi do wymiarowania, pozycjonowania i rysowania elementu. Dokładniej, układ opisuje proces mierzenia i rozmieszczania członków kolekcji Children elementu panelu. Układ to intensywny proces. Im większa kolekcja Children, tym większa liczba obliczeń, które należy wykonać. Złożoność można również wprowadzić na podstawie zachowania układu zdefiniowanego przez element Panel, który jest właścicielem kolekcji. Stosunkowo prosty panel, taki jak Canvas, może mieć znacznie lepszą wydajność niż bardziej złożony panel, taki jak Grid.

Za każdym razem, gdy element podrzędny UIElement zmienia swoją pozycję, może wyzwolić nowy przebieg przez system układu. Dlatego ważne jest, aby zrozumieć zdarzenia, które mogą wywołać system układu, ponieważ niepotrzebne wywołanie może prowadzić do słabej wydajności aplikacji. Poniżej opisano proces, który występuje po wywołaniu systemu układu.

1. Element podrzędny UIElement rozpoczyna proces tworzenia układu od zmierzenia jego podstawowych właściwości.

2. Oceniane są właściwości rozmiaru zdefiniowane w FrameworkElement, takie jak Width, Height i Margin.

3. Stosowana jest logika specyficzna dla panelu, na przykład kierunek dokowania lub orientacja układania.

4. Treść jest ułożona po zmierzeniu wszystkich dzieci.

5. Na ekranie rysowana jest kolekcja Dzieci.

6. Proces jest wywoływany ponownie, jeśli do kolekcji zostaną dodane dodatkowe elementy podrzędne, zastosowana zostanie metoda LayoutTransform lub zostanie wywołana metoda UpdateLayout.

Zobacz LayoutSystem_Measure_Arrange, aby uzyskać więcej informacji na temat pomiaru i organizowania dzieci

LayoutSystem_Performance :

Układ jest procesem rekurencyjnym. Każdy element podrzędny w kolekcji Children jest przetwarzany podczas każdego wywołania systemu układu. W rezultacie należy unikać uruchamiania układu układu, gdy nie jest to konieczne. Poniższe uwagi mogą pomóc w osiągnięciu lepszej wydajności.

Należy pamiętać, które zmiany wartości właściwości wymuszą aktualizację cykliczną przez system układu.

Właściwości zależności, których wartości mogą spowodować zainicjowanie systemu układu, są oznaczone flagami publicznymi. AffectsMeasure i AffectsArrange zapewniają przydatne wskazówki, które zmiany wartości właściwości wymuszą cykliczną aktualizację przez system układu. Ogólnie rzecz biorąc, każda właściwość, która może wpływać na rozmiar obwiedni elementu, powinna mieć flagę AffectsMeasure ustawioną na true. Aby uzyskać więcej informacji, zobacz Omówienie właściwości zależności.

Jeśli to możliwe, użyj RenderTransform zamiast LayoutTransform.

LayoutTransform może być bardzo użytecznym sposobem wpływania na zawartość interfejsu użytkownika (UI). Jeśli jednak efekt transformacji nie musi wpływać na położenie innych elementów, najlepiej zamiast tego użyć RenderTransform, ponieważ RenderTransform nie wywołuje układu układu. LayoutTransform stosuje swoją transformację i wymusza cykliczną aktualizację układu w celu uwzględnienia nowej pozycji elementu, na który ma to wpływ.

Unikaj niepotrzebnych wywołań UpdateLayout.

Metoda UpdateLayout wymusza cykliczną aktualizację układu i często nie jest konieczna. Jeśli nie masz pewności, że wymagana jest pełna aktualizacja, polegaj na systemie układu, który wywoła tę metodę za Ciebie.

Podczas pracy z dużą kolekcją Children rozważ użycie VirtualizingStackPanel zamiast zwykłego StackPanel.

Wirtualizując kolekcję podrzędną, VirtualizingStackPanel przechowuje tylko obiekty w pamięci, które są obecnie w ViewPort elementu nadrzędnego. W rezultacie w większości scenariuszy wydajność znacznie się poprawiła.

Optymalizacja wydajności: układ i projekt : ten artykuł zawiera szczegółowe informacje na temat wydajnego tworzenia drzewa i podaje prostą listę paneli na podstawie ich złożoności

Płótno (najmniej złożone = bardziej wydajne i lepsze działanie)

Krata

Inne panele (bardziej złożone = mniej wydajne i gorsza wydajność)

Inne kwestie dotyczące wydajności, na które należy zwrócić uwagę: Sposoby poprawy szybkości renderowania interfejsu użytkownika WPF

  1. Buforuj wszystko. Pędzle, kolory, geometrie, sformatowane teksty, glify. (Na przykład mamy dwie klasy: RenderTools i TextCache. Proces renderowania adresów każdej jednostki do współdzielonej instancji obu klas. Jeśli więc dwa wykresy mają ten sam tekst, jego przygotowanie jest wykonywane tylko raz.)
  2. Freeze Freezable, jeśli planujesz używać go przez długi czas. Zwłaszcza geometrie. Złożone, niezamrożone geometrie wykonują HitTest bardzo wolno.
  3. Wybierz najszybsze sposoby renderowania każdego prymitywu. Na przykład istnieje około 6 sposobów renderowania tekstu, ale najszybszy jest DrawingContext.DrawGlyphs.
  4. Włącz recykling kontenerów. Wirtualizacja przynosi wiele ulepszeń wydajności, ale kontenery zostaną usunięte i ponownie utworzone, jest to ustawienie domyślne. Możesz jednak uzyskać większą wydajność, poddając recyklingowi kontenery, ustawiając VirtualizingStackPanel.VirtualizationMode = "Recykling"
  5. Od tutaj : Nie ma praktycznego ograniczenia co do ilości gniazdowania, że aplikacja może obsługiwać, jednak na ogół najlepiej ograniczyć swoją aplikację do korzystania tylko te panele, które są rzeczywiście niezbędne do żądanego układu. W wielu przypadkach element Grid może być używany zamiast paneli zagnieżdżonych ze względu na jego elastyczność jako kontener układu. Może to zwiększyć wydajność aplikacji, usuwając niepotrzebne elementy z drzewa.

2
Ta odpowiedź składa się prawie wyłącznie z kopiowania i wklejania z innych źródeł, z których niektóre nie są przypisane. Byłoby znacznie lepiej, gdybyś przyciął go tylko do odpowiednich części, poprawnie przypisał wszystkie źródła i spróbował bardziej bezpośrednio odpowiedzieć na pytanie.
N_A

2
@mydogisbox Odpowiedzią jest kompilacja informacji, wiele z tych samych witryn, które wykorzystałeś w swojej odpowiedzi, mogę dodać. Aby nie brać pod uwagę innych aspektów, które zmieniają działanie, mogą prowadzić do niekompletnej odpowiedzi lub pytającego nadal mieć dodatkowe pytania, więc zdecydowałem się je uwzględnić. Chociaż Rachel z niesamowitym reprezentantem 21,7K i dużym doświadczeniem w WPF może już znać te informacje, inni, którzy patrzą na to pytanie, mogą chcieć tych dodatkowych i istotnych informacji wraz z odpowiedzią.
Erick
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.