In welcher Reihenfolge sind Panels hinsichtlich Renderzeit und Leistung am effizientesten?


127

Es gibt viele Fälle, in denen mehr als ein Bedienfeld für das gewünschte Layout geeignet ist. Ich weiß jedoch, dass die Renderzeiten für verschiedene Bedienfeldtypen unterschiedlich sind.

MSDN gibt dies beispielsweise an

Ein relativ einfaches Panelwie Canvaskann eine deutlich bessere Leistung haben als ein komplexeres Panelwie Grid.

In welcher Reihenfolge sind WPF-Panels in Bezug auf Renderzeit und Leistung am effizientesten?

WPF-Panels:

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

Ich bin mir ziemlich sicher, dass ich irgendwo online eine Liste davon gesehen habe, aber ich kann sie jetzt nicht finden.

Die ideale Antwort, die ich suche, würde mir eine Liste von Panels in der Reihenfolge liefern, in der sie am schnellsten gerendert werden. Ich verstehe, dass die Anzahl der Kinder ein wichtiger Faktor für die Effizienz der Panels ist. Nehmen wir für diese Frage an, dass jedes Panel nur ein Label/ hatTextBox Paar hat.

Darüber hinaus möchte ich eine Liste von Ausnahmen, z. B. bestimmte Panels, die unter bestimmten Bedingungen eine bessere Leistung als andere erbringen.

Aktualisieren

Zusammenfassend lässt sich sagen , dass die Panel-Leistung basierend auf der akzeptierten Antwort unten auf der Anzahl und dem Layout der untergeordneten Elemente basiert. Im Allgemeinen lautet die Liste vom schnellsten zum langsamsten jedoch:

  • Canvas
  • StackPanel
  • WrapPanel
  • DockPanel
  • Grid

Außerdem sollte immer ein VirtualizingPanel/ VirtualizingStackPanelverwendet werden, wenn viele Elemente nicht immer auf den Bildschirm passen.

Ich würde Ihnen wärmstens empfehlen, die unten stehende akzeptierte Antwort zu lesen, bevor Sie einen Artikel aus dieser Liste auswählen.


Ist es naiv anzunehmen, dass Virtualisierungs-Panels ausnahmslos eine bessere Leistung erbringen als Nicht-Virtualisierungs-Panels?
BoltClock

@BoltClock Ich denke, es hängt davon ab, wie viel nicht sichtbarer Inhalt sich im Panel befindet. Wenn es viele nicht sichtbare Elemente gibt, VirtualizingStackPanelwird a definitiv eine bessere Leistung erzielen, aber wenn alle im Bedienfeld angezeigten Elemente sichtbar sind, ist es meiner Meinung nach besser, ein normales Bedienfeld zu verwenden.
Rachel

Vielen Dank. Es ist sinnvoll, dass es sich um eine Verschwendung von Virtualisierungselementen handelt, wenn alle ohnehin angezeigt werden.
BoltClock

Abgesehen von der Virtualisierung haben sie unterschiedliche Funktionen, oder sie wären keine separaten Steuerelemente. Ich gehe mit dem, was dem Kunden die beste Benutzeroberfläche bietet.
Paparazzo

1
Sind Sie sicher, dass es einen spürbaren Unterschied gibt (abgesehen von der Virtualisierung)? Sie müssen lediglich einen relativ einfachen Layout-Algorithmus ausführen. Winzig im Vergleich zu allen folgenden Renderings. Allerdings wird das Raster wahrscheinlich das langsamste sein (gewichtete Skalierung).
Henk Holterman

Antworten:


130

Ich denke, es ist prägnanter und verständlicher, die Leistungsmerkmale jedes Panels zu beschreiben, als zu versuchen, einen absoluten relativen Leistungsvergleich zu erstellen.

WPF führt beim Rendern von Inhalten zwei Durchgänge durch: Messen und Anordnen. Jedes Panel weist für jeden dieser beiden Durchgänge unterschiedliche Leistungsmerkmale auf.

Die Leistung des Messdurchlaufs wird am stärksten von der Fähigkeit eines Panels beeinflusst, das Dehnen mithilfe von Ausrichtungen (oder im Fall von Auto Grid) und dann von der Anzahl der Kinder, die gedehnt oder automatisch dimensioniert werden, zu berücksichtigen. Die Leistung des Arrangierpasses wird durch die Komplexität der Interaktion zwischen dem Layoutort verschiedener Kinder und dann natürlich der Anzahl der Kinder beeinflusst.

Manchmal eignen sich die angegebenen Panels nicht leicht für das erforderliche Layout. Ich habe ein Steuerelement erstellt, bei dem eine beliebige Anzahl von Elementen an einem bestimmten Prozentsatz des verfügbaren Speicherplatzes positioniert werden muss. Keines der Standardsteuerelemente tut dies. Der Versuch, sie dazu zu bringen (durch Bindung an die tatsächliche Größe des Elternteils), führt zu einer schrecklichen Leistung. Ich habe ein Layout-Panel basierend auf der Leinwand erstellt, das mit minimalem Aufwand mein gewünschtes Ergebnis erzielt hat (ich habe die Quelle für die Leinwand kopiert und etwa 20 Zeilen davon geändert).

Verfügbare Panels:

  • Segeltuch

    Definiert einen Bereich, in dem Sie untergeordnete Elemente explizit durch Koordinaten relativ zum Canvas-Bereich positionieren können.

    Die Leinwand bietet die beste Leistung aller Panels für den Arrangierpass, da jedem Element statisch ein Standort zugewiesen ist. Der Messpass hat auch eine hervorragende Leistung, da es in diesem Panel kein Konzept zum Dehnen gibt. Jedes Kind verwendet einfach seine native Größe.

  • DockPanel

    Definiert einen Bereich, in dem Sie untergeordnete Elemente entweder horizontal oder vertikal relativ zueinander anordnen können.

    Das Dockpanel verfügt über ein sehr einfaches Layoutschema, bei dem Elemente nacheinander relativ zum zuvor hinzugefügten Element hinzugefügt werden. Standardmäßig wird entweder die Höhe oder die Breite durch die native Größe des Elements bestimmt (basierend auf oben / unten bzw. links / rechts), und die andere Richtung wird durch die DockEigenschaft bestimmt, wenn die Breite oder Höhe undefiniert ist. Mittlerer bis schneller Messpass und mittlerer bis schneller Arrangement-Pass.

  • Gitter

    Definiert einen flexiblen Rasterbereich, der aus Spalten und Zeilen besteht.

    Dies kann das leistungsintensivste Panel sein, wenn eine proportionale oder automatische Dimensionierung verwendet wird. Die Berechnung der Größe des untergeordneten Elements kann eine komplexe Kombination aus der nativen Größe des Elements und dem vom Raster angegebenen Layout sein. Das Layout ist auch das komplizierteste aller Panels. Langsame bis mittlere Leistung für den Messdurchlauf und langsame bis mittlere Leistung für den Arrangementdurchlauf.

  • StackPanel

    Ordnet untergeordnete Elemente in einer einzelnen Linie an, die horizontal oder vertikal ausgerichtet werden kann.

    Das StackPanel misst seine Kinder entweder mit nativer oder relativer Größe in entgegengesetzter Richtung zu seiner Ausrichtung und mit nativer Größe in Richtung seiner Ausrichtung (Ausrichtung bewirkt nichts in dieser Richtung). Dies macht es zu einem mittelständischen Künstler in diesem Bereich. Der Arrangement-Pass besteht einfach darin, die Artikel der Reihe nach auszulegen. Wahrscheinlich die zweitbeste Leistung für diesen Pass. Mittlere Leistung für den Messdurchlauf und schnelle Leistung für den Layoutdurchlauf.

  • VirtualizingPanel

    Bietet ein Framework für Panel-Elemente, die die untergeordnete Datenerfassung virtualisieren. Dies ist eine abstrakte Klasse.

    Eine Basisklasse zum Implementieren Ihres eigenen Virtualisierungspanels. Lädt nur sichtbare Elemente, um eine unnötige Verwendung von Speicher und Prozessor zu verhindern. VIEL leistungsfähiger für Sätze von Gegenständen. Wahrscheinlich etwas weniger leistungsfähig für Elemente, die aufgrund der Grenzüberprüfung auf den Bildschirm passen. Das SDK bietet nur eine Unterklasse davon, die VirtualizingStackPanel.

  • WrapPanel

    Positioniert untergeordnete Elemente in einer sequentiellen Position von links nach rechts und unterbricht den Inhalt in der nächsten Zeile am Rand des enthaltenen Felds. Die nachfolgende Reihenfolge erfolgt je nach Wert der Orientation-Eigenschaft nacheinander von oben nach unten oder von rechts nach links.

    Der Messdurchlauf ist ein etwas komplexer Durchgang, bei dem das größte Element für eine bestimmte Zeile die Höhe der Zeile bestimmt und dann jedes Element in dieser Zeile entweder seine native Höhe (falls vorhanden) oder die Höhe der Zeile verwendet. Der Layout-Durchgang ist einfach: Platzieren Sie jedes Element nacheinander in einer Reihe und fahren Sie dann mit der nächsten Reihe fort, wenn nicht genügend Platz für das nächste Element vorhanden ist. Mittlere Leistungsmessung bestanden. Mittlere bis schnelle Leistung für den Arrangement-Pass.

Verweise:

Verwenden Sie nach Möglichkeit das effizienteste Panel

Die Komplexität des Layoutprozesses basiert direkt auf dem Layoutverhalten der von Panel abgeleiteten Elemente, die Sie verwenden. Beispielsweise bietet ein Grid- oder StackPanel-Steuerelement viel mehr Funktionen als ein Canvas-Steuerelement. Der Preis für diese größere Erhöhung der Funktionalität ist eine größere Erhöhung der Leistungskosten. Wenn Sie jedoch nicht die Funktionalität benötigen, die ein Grid-Steuerelement bietet, sollten Sie die kostengünstigeren Alternativen verwenden, z. B. eine Leinwand oder ein benutzerdefiniertes Bedienfeld.

Von der Leistungsoptimierung: Layout und Design

Das Layoutsystem führt für jedes Mitglied der Children-Sammlung zwei Durchgänge durch, einen Messpass und einen Arrangierpass. Jedes untergeordnete Bedienfeld bietet seine eigenen MeasureOverride- und ArrangeOverride-Methoden, um ein spezifisches Layoutverhalten zu erzielen.

Während des Messdurchlaufs wird jedes Mitglied der Children-Sammlung bewertet. Der Prozess beginnt mit einem Aufruf der Measure-Methode. Diese Methode wird in der Implementierung des übergeordneten Panel-Elements aufgerufen und muss nicht explizit aufgerufen werden, damit das Layout ausgeführt wird.

Zunächst werden native Größeneigenschaften des UIElement ausgewertet, z. B. Clip und Sichtbarkeit. Dadurch wird ein Wert mit dem Namen ConstraintSize generiert, der an MeasureCore übergeben wird.

Zweitens werden in FrameworkElement definierte Framework-Eigenschaften verarbeitet, was sich auf den Wert von ConstraintSize auswirkt. Diese Eigenschaften beschreiben im Allgemeinen die Größenmerkmale des zugrunde liegenden UIElement, wie z. B. Höhe, Breite, Rand und Stil. Jede dieser Eigenschaften kann den Platz ändern, der zum Anzeigen des Elements erforderlich ist. MeasureOverride wird dann mit ConstraintSize als Parameter aufgerufen.

Hinweis Es gibt einen Unterschied zwischen den Eigenschaften von Höhe und Breite und ActualHeight und ActualWidth. Beispielsweise ist die ActualHeight-Eigenschaft ein berechneter Wert, der auf anderen Höheneingaben und dem Layoutsystem basiert. Der Wert wird vom Layoutsystem selbst basierend auf einem tatsächlichen Rendering-Durchlauf festgelegt und kann daher geringfügig hinter dem festgelegten Wert von Eigenschaften wie z. B. Höhe zurückbleiben, die der Eingabeänderung zugrunde liegen. Da ActualHeight ein berechneter Wert ist, sollten Sie sich darüber im Klaren sein, dass aufgrund verschiedener Vorgänge des Layoutsystems mehrere oder inkrementelle gemeldete Änderungen daran vorgenommen werden können. Das Layoutsystem kann den erforderlichen Messraum für untergeordnete Elemente, Einschränkungen durch das übergeordnete Element usw. berechnen. Das ultimative Ziel des Messpasses besteht darin, dass das Kind seine gewünschte Größe bestimmt. Dies tritt während des MeasureCore-Aufrufs auf. Der DesiredSize-Wert wird von Measure zur Verwendung während des Inhaltsanordnungsdurchlaufs gespeichert.

Der Arrangierpass beginnt mit einem Aufruf der Arrangiermethode. Während des Arrangierdurchlaufs generiert das übergeordnete Panel-Element ein Rechteck, das die Grenzen des untergeordneten Elements darstellt. Dieser Wert wird zur Verarbeitung an die ArrangeCore-Methode übergeben.

Die ArrangeCore-Methode wertet die DesiredSize des untergeordneten Elements aus und wertet alle zusätzlichen Ränder aus, die sich auf die gerenderte Größe des Elements auswirken können. ArrangeCore generiert eine arrangSize, die als Parameter an die ArrangeOverride-Methode des Panels übergeben wird. ArrangeOverride generiert die endgültige Größe des untergeordneten Elements. Schließlich führt die ArrangeCore-Methode eine endgültige Bewertung der Versatz-Eigenschaften wie Rand und Ausrichtung durch und platziert das untergeordnete Element in seinem Layout-Slot. Das Kind muss (und wird häufig nicht) nicht den gesamten zugewiesenen Platz ausfüllen. Die Steuerung wird dann an das übergeordnete Bedienfeld zurückgegeben und der Layoutprozess ist abgeschlossen.

Vom Messen und Ordnen von Kindern


1
Antwort auf einen jetzt gelöschten Kommentar: Ich habe keine Metriken eingefügt, da diese nicht hilfreich wären. Es gibt zu viele Kombinationen, als dass eine Tabelle nützlich wäre. Eine nützlichere Methode zur Optimierung der Leistung wäre die Verwendung eines allgemeinen Verständnisses zur Auswahl der anfänglichen Layout-Panels und die anschließende Optimierung nach Bedarf mithilfe einer Analyse der tatsächlichen Situation.
N_A

Vielen Dank, Ihre Erklärung, wie WPF-Panels tatsächlich gerendert werden, und die Measure / Arrange-Leistung jedes Panels ist weitaus besser als das, wonach ich gefragt habe :)
Rachel

@mydogisbox Ich sehe UniformGridnirgendwo auf Ihrer Liste. Könnten Sie Ihre Antwort mit diesem Panel und der geschätzten Mess- / Anordnungsleistung im Verhältnis zu den anderen Panel-Typen aktualisieren?
Rachel

1
@Rachel Das UniformGridist nicht für die Verwendung im Anwendungslayout vorgesehen. Weitere Informationen finden Sie unter "Abgeleitete Panel-Elemente" hier: msdn.microsoft.com/en-us/library/ms754152.aspx . In Bezug auf die Geschwindigkeit sollte es etwas schneller als a DockPanelund etwas langsamer als a sein Canvas.
N_A

12

Vielleicht dies wird Ihnen helfen.

Nicht nur für Panels, sondern auch für jede Anwendung, die Sie in WPF erstellen möchten.

Es schließt die Zeichnungs- und Messleistung von WPF ab.

Es enthält außerdem eine Zeichnungstestanwendung, Ergebnisse und Schlussfolgerungen für verschiedene Betriebssysteme, auf die Sie abzielen möchten.


8

Die Panels, die Sie erwähnen, sind Layout-Panels. Ein kurzer Überblick über das Layout-System legt daher nahe, dass es sich wahrscheinlich nicht nur um eine einfache Liste der effizientesten Panels handelt, sondern auch darum, wie Sie die Panels verwenden, die den größten Einfluss auf Effizienz und Leistung haben.

LayoutSystem_Übersicht :

Im einfachsten Fall ist das Layout ein rekursives System, das dazu führt, dass ein Element dimensioniert, positioniert und gezeichnet wird. Insbesondere beschreibt das Layout den Prozess des Messens und Anordnens der Mitglieder der Children-Sammlung eines Panel-Elements. Layout ist ein intensiver Prozess. Je größer die Children-Sammlung ist, desto mehr Berechnungen müssen durchgeführt werden. Komplexität kann auch basierend auf dem Layoutverhalten eingeführt werden, das durch das Panel-Element definiert wird, dem die Sammlung gehört. Ein relativ einfaches Panel wie Canvas kann eine deutlich bessere Leistung aufweisen als ein komplexeres Panel wie Grid.

Jedes Mal, wenn ein untergeordnetes UIElement seine Position ändert, kann es einen neuen Durchgang durch das Layoutsystem auslösen. Daher ist es wichtig, die Ereignisse zu verstehen, die das Layoutsystem aufrufen können, da ein unnötiger Aufruf zu einer schlechten Anwendungsleistung führen kann. Im Folgenden wird der Prozess beschrieben, der beim Aufrufen des Layoutsystems auftritt.

1. Ein untergeordnetes UIElement beginnt den Layoutprozess, indem zunächst seine Kerneigenschaften gemessen werden.

2. In FrameworkElement definierte Größeneigenschaften werden ausgewertet, z. B. Breite, Höhe und Rand.

3. Es wird eine Panel-spezifische Logik angewendet, z. B. Dock-Richtung oder Stapelausrichtung.

4. Der Inhalt wird angeordnet, nachdem alle Kinder gemessen wurden.

5. Die Sammlung Kinder wird auf dem Bildschirm gezeichnet.

6. Der Prozess wird erneut aufgerufen, wenn der Auflistung zusätzliche untergeordnete Elemente hinzugefügt, eine LayoutTransform angewendet oder die UpdateLayout-Methode aufgerufen wird.

Weitere Informationen zum Messen und Anordnen von Kindern finden Sie unter LayoutSystem_Measure_Arrange

LayoutSystem_Performance :

Layout ist ein rekursiver Prozess. Jedes untergeordnete Element in einer untergeordneten Auflistung wird bei jedem Aufruf des Layoutsystems verarbeitet. Daher sollte das Auslösen des Layoutsystems vermieden werden, wenn dies nicht erforderlich ist. Die folgenden Überlegungen können Ihnen dabei helfen, eine bessere Leistung zu erzielen.

Beachten Sie, welche Änderungen des Eigenschaftswerts eine rekursive Aktualisierung durch das Layoutsystem erzwingen.

Abhängigkeitseigenschaften, deren Werte dazu führen können, dass das Layoutsystem initialisiert wird, sind mit öffentlichen Flags gekennzeichnet. AffectsMeasure und AffectsArrange liefern nützliche Hinweise darauf, welche Änderungen des Eigenschaftswerts eine rekursive Aktualisierung durch das Layoutsystem erzwingen. Im Allgemeinen sollte für jede Eigenschaft, die sich auf die Größe des Begrenzungsrahmens eines Elements auswirken kann, das AffectsMeasure-Flag auf true gesetzt sein. Weitere Informationen finden Sie unter Übersicht über Abhängigkeitseigenschaften.

Verwenden Sie nach Möglichkeit eine RenderTransform anstelle einer LayoutTransform.

Eine LayoutTransform kann eine sehr nützliche Methode sein, um den Inhalt einer Benutzeroberfläche zu beeinflussen. Wenn sich der Effekt der Transformation jedoch nicht auf die Position anderer Elemente auswirken muss, verwenden Sie stattdessen am besten eine RenderTransform, da RenderTransform das Layoutsystem nicht aufruft. LayoutTransform wendet seine Transformation an und erzwingt eine rekursive Layoutaktualisierung, um die neue Position des betroffenen Elements zu berücksichtigen.

Vermeiden Sie unnötige Aufrufe von UpdateLayout.

Die UpdateLayout-Methode erzwingt eine rekursive Layoutaktualisierung und ist häufig nicht erforderlich. Wenn Sie nicht sicher sind, dass ein vollständiges Update erforderlich ist, verlassen Sie sich auf das Layoutsystem, um diese Methode für Sie aufzurufen.

Wenn Sie mit einer großen Children-Sammlung arbeiten, sollten Sie ein VirtualizingStackPanel anstelle eines regulären StackPanel verwenden.

Durch die Virtualisierung der untergeordneten Sammlung speichert das VirtualizingStackPanel nur Objekte im Speicher, die sich derzeit im ViewPort des übergeordneten Elements befinden. Infolgedessen wird die Leistung in den meisten Szenarien erheblich verbessert.

Optimieren der Leistung: Layout und Design : Dieser Artikel beschreibt ausführlich, wie der Baum effizient erstellt werden kann, und enthält eine einfache Liste der Bedienfelder, die auf ihrer Komplexität basieren

Canvas (am wenigsten komplex = effizienter und leistungsfähiger)

Gitter

Andere Panels (komplexer = weniger effizient und schlechtere Leistung)

Weitere zu berücksichtigende Leistungsaspekte: Möglichkeiten zur Verbesserung der Rendergeschwindigkeit der WPF-Benutzeroberfläche

  1. Alles zwischenspeichern. Pinsel, Farben, Geometrien, formatierte Texte, Glyphen. (Zum Beispiel haben wir zwei Klassen: RenderTools und TextCache. Der Renderprozess jeder Einheitenadresse an die gemeinsam genutzte Instanz beider Klassen. Wenn also zwei Diagramme denselben Text haben, wird ihre Vorbereitung nur einmal ausgeführt.)
  2. Freeze Freezable, wenn Sie es längere Zeit verwenden möchten. Besonders Geometrien. Komplexe nicht gefrorene Geometrien führen HitTest extrem langsam aus.
  3. Wählen Sie die schnellsten Möglichkeiten zum Rendern jedes Grundelements. Zum Beispiel gibt es ungefähr 6 Möglichkeiten zum Rendern von Text, aber die schnellste ist DrawingContext.DrawGlyphs.
  4. Container-Recycling aktivieren. Die Virtualisierung bringt viele Leistungsverbesserungen mit sich, aber die Container werden entsorgt und neu erstellt. Dies ist die Standardeinstellung. Sie können jedoch mehr Leistung erzielen, indem Sie Container recyceln, indem Sie VirtualizingStackPanel.VirtualizationMode = "Recycling" festlegen.
  5. Von hier aus : Es gibt keine praktische Begrenzung für die Verschachtelung, die Ihre Anwendung unterstützen kann. Im Allgemeinen ist es jedoch am besten, Ihre Anwendung so zu beschränken, dass nur die Bereiche verwendet werden, die für Ihr gewünschtes Layout tatsächlich erforderlich sind. In vielen Fällen kann ein Rasterelement aufgrund seiner Flexibilität als Layoutcontainer anstelle verschachtelter Bedienfelder verwendet werden. Dies kann die Leistung in Ihrer Anwendung steigern, indem unnötige Elemente aus dem Baum ferngehalten werden.

2
Diese Antwort besteht fast ausschließlich aus dem Kopieren und Einfügen aus anderen Quellen, von denen einige nicht zugeordnet sind. Es wäre viel besser, wenn Sie es nur auf die relevanten Teile reduzieren, alle Quellen korrekt zuordnen und versuchen würden, die Frage direkter zu beantworten.
N_A

2
@mydogisbox Die Antwort ist eine Zusammenstellung von Informationen, viele der gleichen Websites, die Sie in Ihrer Antwort verwendet haben, könnte ich hinzufügen. Um andere Aspekte, die die Leistung ändern, nicht zu berücksichtigen, kann dies zu einer unvollständigen Antwort führen oder der Fragesteller hat noch zusätzliche Fragen. Deshalb habe ich mich dafür entschieden, diese einzubeziehen. Während Rachel mit einer erstaunlichen 21,7K-Wiederholung und viel WPF-Erfahrung diese Informationen möglicherweise bereits kennt, wünschen sich andere, die sich mit dieser Frage befassen, möglicherweise diese zusätzlichen und relivanten Informationen zusammen mit der Antwort.
Erick
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.