Tipps zu MVVM und SprachleistungMVVM and language performance tips

In diesem Thema werden einige Leistungsaspekte in Bezug auf die Wahl von Softwaredesignmustern und Programmiersprachen erläutert.This topic discusses some performance considerations related to your choice of software design patterns, and programming language.

Das Model-View-ViewModel (MVVM)-MusterThe Model-View-ViewModel (MVVM) pattern

Das Model-View-ViewModel (MVVM)-Muster kommt in zahlreichen XAML-Apps zur Anwendung.The Model-View-ViewModel (MVVM) pattern is common in a lot of XAML apps. (MVVM ähnelt sehr stark dem von Fowler beschriebenen Model-View-Presenter-Muster, ist aber speziell auf XAML zugeschnitten.)(MVVM is very similar to Fowler’s description of the Model-View-Presenter pattern, but it is tailored to XAML). Das Problem mit dem MVVM-Muster: Es kann zu Apps mit zu vielen Ebenen und Zuordnungen führen.The issue with the MVVM pattern is that it can inadvertently lead to apps that have too many layers and too many allocations. Vorteile von MVVM:The motivations for MVVM are these.

  • Aufgabenteilung.Separation of concerns. Es ist immer hilfreich, ein Problem in kleinere Teile zu zerlegen. Mit einem Muster wie MVVM oder MVC können Sie eine App (und sogar ein einzelnes Steuerelement) in die eigentliche Ansicht, ein logisches Modell der Ansicht (Ansichtsmodell) und die von der Ansicht unabhängige App-Logik (das Modell) unterteilen.It’s always helpful to divide a problem into smaller pieces, and a pattern like MVVM or MVC is a way to divide an app (or even a single control) into smaller pieces: the actual view, a logical model of the view (view-model), and the view-independent app logic (the model). Dabei hat es sich bewährt, dass sich die Designer mit einem Tool um die Ansicht, die Entwickler mit einem anderen Tool um das Modell und die Designintegratoren mit beiden Tools um Ansicht und Modell kümmern.In particular, it’s a popular workflow to have designers own the view using one tool, developers own the model using another tool, and design integrators own the view-model using both tools.
  • Modultests.Unit testing. Für das Ansichtsmodell (und letztlich auch für das Modell) können Modultests durchgeführt werden, die von der Ansicht und somit von Fenstererstellung, Eingaben usw. unabhängig sind.You can unit test the view-model (and consequently the model) independent of the view, thereby not relying on creating windows, driving input, and so on. Dank einer klein gehaltenen Ansicht können Sie einen großen Teil Ihrer App testen, ohne jemals ein Fenster erstellen zu müssen.By keeping the view small, you can test a large portion of your app without ever having to create a window.
  • Flexibilität beim Ändern der Benutzererfahrung.Agility to user experience changes. Die Ansicht wird in der Regel besonders häufig und meistens zuletzt geändert, wenn die Benutzeroberfläche auf der Grundlage von Endbenutzerfeedback optimiert wird.The view tends to see the most frequent changes, and the most late changes, as the user experience is tweaked based on end-user feedback. Durch die getrennte Behandlung der Ansicht lassen sich diese Änderungen schneller und mit geringeren Auswirkungen auf die App implementieren.By keeping the view separate, these changes can be accommodated more quickly and with less churn to the app.

Es gibt mehrere konkrete Definitionen des MVVM-Musters sowie Drittanbieter-Frameworks, die Sie bei der Implementierung unterstützen.There are multiple concrete definitions of the MVVM pattern, and 3rd party frameworks that help implement it. Die strikte Einhaltung jeglicher Variante des Musters kann jedoch dazu führen, dass der Zusatzaufwand für eine App jedes vernünftige Maß übersteigt.But strict adherence to any variation of the pattern can lead to apps with a lot more overhead than can be justified.

  • Die XAML-Datenbindung ({Binding}-Markuperweiterung) wurde unter anderem für die Verwendung von Modell/Ansicht-Mustern entwickelt.XAML data binding (the {Binding} markup extension) was designed in part to enable model/view patterns. {Binding} ist jedoch mit einer hohen Arbeitssatz- und CPU-Auslastung verbunden.But {Binding} brings with it non-trivial working set and CPU overhead. Die Erstellung einer Bindung führt zu einer Reihe von Zuordnungen, und die Aktualisierung eines Bindungsziels kann zu Reflektion und Boxing führen.Creating a {Binding} causes a series of allocations, and updating a binding target can cause reflection and boxing. Diese Probleme werden mit der {x:Bind}-Markuperweiterung behandelt, die die Bindung zur Erstellungszeit kompiliert.These problems are being addressed with the {x:Bind} markup extension, which compiles the bindings at build time. Empfehlung: Verwenden Sie {x:Bind}.Recommendation: use {x:Bind}.
  • Bei MVVM wird „Button.Click“ gerne mithilfe eines gängigen ICommand-Hilfsbefehls wie „DelegateCommand“ oder „RelayCommand“ mit dem Ansichtsmodell verknüpft.It’s popular in MVVM to connect Button.Click to the view-model using an ICommand, such as the common DelegateCommand or RelayCommand helpers. Bei diesen Befehlen handelt es sich jedoch um zusätzliche Zuordnungen (einschließlich des CanExecuteChanged-Ereignislisteners), die den Arbeitssatz vergrößern und die Start-/Navigationszeiten für die Seite erhöhen.Those commands are extra allocations, though, including the CanExecuteChanged event listener, adding to the working set, and adding to the startup/navigation time for the page. Empfehlung: Ziehe als Alternative zur Verwendung der praktischen ICommand-Schnittstelle die Verwendung von Ereignishandlern im CodeBehind in Betracht. Diese kannst du dann mit den Ansichtsereignissen verknüpfen und bei deren Auslösung einen Befehl für Ihr Ansichtsmodell aufrufen.Recommendation: As an alternative to using the convenient ICommand interface, consider putting event handlers in your code-behind and attaching them to the view events and call a command on your view-model when those events are raised. Darüber hinaus müssen Sie zusätzlichen Code hinzufügen, um die Schaltfläche zu deaktivieren, wenn der Befehl nicht verfügbar ist.You'll also need to add extra code to disable the Button when the command is unavailable.
  • Bei Verwendung von MVVM erstellen Entwickler gerne eine Seite mit allen möglichen UI-Konfigurationen und reduzieren dann Teile der Struktur, indem sie die Visibility-Eigenschaft an Eigenschaften des Ansichtsmodells binden.It’s popular in MVVM to create a Page with all possible configurations of the UI, then collapse parts of the tree by binding the Visibility property to properties in the VM. Dadurch erhöht sich unnötig die Startzeit, und auch der Arbeitssatz kann sich unnötig vergrößern, da einige Teile der Struktur möglicherweise gar nicht angezeigt werden.This adds unnecessarily to startup time and possibly to working set (because some parts of the tree may never become visible). Empfehlungen: Verwende das Feature x:Load attribute oder x:DeferLoadStrategy attribute, um unnötige Teile der Struktur aus dem Startvorgang zu entfernen.Recommendations: Use the x:Load attribute or x:DeferLoadStrategy attribute feature to defer unnecessary portions of the tree out of startup. Erstellen Sie außerdem separate Benutzersteuerelemente für die verschiedenen Modi der Seite, und sorgen Sie mithilfe des CodeBehind dafür, dass nur die benötigten Steuerelemente geladen bleiben.Also, create separate user controls for the different modes of the page and use code-behind to keep only the necessary controls loaded.

Empfehlungen für C++/CXC++/CX recommendations

  • Verwenden Sie die jeweils aktuelle Version.Use the latest version. Die Leistung des C++/CX-Compilers wird kontinuierlich optimiert.There are continual performance improvements made to the C++/CX compiler. Verwenden Sie für die App-Erstellung das neueste Toolset.Ensure your app is building using the latest toolset.
  • Deaktivieren Sie RTTI (/GR-) .Disable RTTI (/GR-). RTTI ist im Compiler standardmäßig aktiviert. Sofern die Option also nicht durch Ihre Buildumgebung deaktiviert wird, verwenden Sie sie wahrscheinlich.RTTI is on by default in the compiler so, unless your build environment switches it off, you’re probably using it. RTTI verursacht einen erheblichen Mehraufwand und sollte deaktiviert werden, sofern Ihr Code nicht davon abhängig ist.RTTI has significant overhead, and unless your code has a deep dependency on it, you should turn it off. Das XAML-Framework erfordert keine Verwendung von RTTI in Ihrem Code.The XAML framework has no requirement that your code use RTTI.
  • Setzen Sie PPL-Aufgaben sparsam ein.Avoid heavy use of ppltasks. PPL-Aufgaben sind beim Aufrufen asynchroner WinRT-APIs äußerst praktisch, vergrößern aber erheblich den Codeumfang.Ppltasks are very convenient when calling async WinRT APIs, but they come with significant code size overhead. Das C++/CX-Team arbeitet an einem Programmiersprachenfeature namens „await“, das die Leistung deutlich verbessert.The C++/CX team is working on a language feature – await – that will provide much better performance. Vorerst empfiehlt es sich jedoch, PPL-Aufgaben an den langsamsten Pfaden Ihres Codes nur sehr sparsam einzusetzen.In the meantime, balance your use of ppltasks in the hot paths of your code.
  • Vermeiden Sie die Verwendung von C++/CX in der Geschäftslogik Ihrer App.Avoid use of C++/CX in the “business logic” of your app. C++/CX ist für den komfortablen Zugriff auf WinRT-APIs in C++-Apps konzipiert.C++/CX is designed to be a convenient way to access WinRT APIs from C++ apps. Die dabei verwendeten Wrapper bedeuten einen Zusatzaufwand.It makes use of wrappers that have overhead. Daher empfiehlt es sich, innerhalb der Geschäftslogik bzw. des Modells Ihrer Klasse auf den Einsatz von C++/CX zu verzichten und es nur an der Grenze zwischen Ihrem Code und WinRT zu verwenden.You should avoid C++/CX inside the business logic/model of your class, and reserve it for use at the boundaries between your code and WinRT.