Sugerencias de rendimiento de MVVM y lenguajeMVVM and language performance tips

En este tema se describen algunos aspectos a tener en cuenta acerca del rendimiento y que están relacionados con la elección de patrones de diseño del software y del lenguaje de programación.This topic discusses some performance considerations related to your choice of software design patterns, and programming language.

Patrón Model-View-ViewModel (MVVM)The Model-View-ViewModel (MVVM) pattern

El patrón Model-View-ViewModel (MVVM) es común en muchas aplicaciones XAML.The Model-View-ViewModel (MVVM) pattern is common in a lot of XAML apps. (MVVM es muy similar a la descripción del Fowler del patrón Model-View-Presenter, pero se ha adaptado para XAML).(MVVM is very similar to Fowler’s description of the Model-View-Presenter pattern, but it is tailored to XAML). El problema con el patrón MVVM es que puede provocar inadvertidamente aplicaciones con demasiadas capas y demasiadas asignaciones.The issue with the MVVM pattern is that it can inadvertently lead to apps that have too many layers and too many allocations. Estas son las motivaciones para el uso de MVVM.The motivations for MVVM are these.

  • Separación de problemas.Separation of concerns. Siempre es útil dividir un problema en partes más pequeñas y un patrón como MVVM o MVC es una forma de dividir una aplicación (o incluso un control único) en partes más pequeñas: la vista real, un modelo lógico de la vista (modelo de vista) y la lógica de aplicación independiente de la vista (el modelo).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). En particular, es un flujo de trabajo popular para que los diseñadores posean la vista con una herramienta, los desarrolladores posean el modelo con otra herramienta los integradores de diseño posean el modelo de vista con ambas herramientas.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.
  • Pruebas de unidad.Unit testing. Puedes realizar la prueba de unidad para el modelo de vista (y, en consecuencia, el modelo) independiente de la vista, por lo que no hace falta depender de la creación de ventanas, impulsar entradas, etc.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. Al mantener la vista pequeña, puedes probar una gran parte de la aplicación sin tener que crear una ventana.By keeping the view small, you can test a large portion of your app without ever having to create a window.
  • Agilidad en los cambios de la experiencia del usuario.Agility to user experience changes. La vista suele ver los cambios más frecuentes y los más recientes, a medida que la experiencia del usuario se ajusta en función de los comentarios de los usuarios finales.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. Al mantener la vista independiente, estos cambios se pueden aplicar más rápidamente y con menos renovación de la aplicación.By keeping the view separate, these changes can be accommodated more quickly and with less churn to the app.

Hay varias definiciones concretas del patrón MVVM y marcos de terceros que ayudan a implementarlo.There are multiple concrete definitions of the MVVM pattern, and 3rd party frameworks that help implement it. Sin embargo, una adherencia estricta a cualquier variación del patrón puede resultar en aplicaciones con mucha más sobrecarga que se pueda justificar.But strict adherence to any variation of the pattern can lead to apps with a lot more overhead than can be justified.

  • Los enlaces de datos XAML (la extensión de marcado {Binding}) se diseñaron en parte para habilitar los patrones de modelos y vistas.XAML data binding (the {Binding} markup extension) was designed in part to enable model/view patterns. Sin embargo, {Binding} aporta un conjunto de trabajo no trivial y la sobrecarga de la CPU.But {Binding} brings with it non-trivial working set and CPU overhead. La creación de un elemento {Binding} provoca una serie de asignaciones, y la actualización de un destino de enlace puede provocar reflejos y conversiones boxing.Creating a {Binding} causes a series of allocations, and updating a binding target can cause reflection and boxing. Estos problemas se han solucionado con la extensión de marcado {x:Bind}, que compila los enlaces en tiempo de compilación.These problems are being addressed with the {x:Bind} markup extension, which compiles the bindings at build time. Recomendación: usa {x:Bind}.Recommendation: use {x:Bind}.
  • Es común en MVVM conectar Button.Click al modelo de vista con un objeto ICommand, tales como las aplicaciones auxiliares comunes DelegateCommand o RelayCommand.It’s popular in MVVM to connect Button.Click to the view-model using an ICommand, such as the common DelegateCommand or RelayCommand helpers. Sin embargo, estos comandos son asignaciones adicionales, incluido el agente de escucha de eventos CanExecuteChanged, lo que agrega al conjunto de trabajo y al tiempo de inicio o navegación de la página.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. Recomendación: como alternativa al uso de la cómoda interfaz ICommand, podrías colocar los controladores de eventos en el código subyacente, adjuntarlos a los eventos de vista y llamar a un comando en la vista de modelos cuando se generen los eventos.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. También tendrás que agregar código adicional para deshabilitar el elemento Button cuando el comando no está disponible.You'll also need to add extra code to disable the Button when the command is unavailable.
  • Es común en MVVM crear una página con todas las configuraciones posibles de la interfaz de usuario y luego contraer partes del árbol enlazando la propiedad Visibility a las propiedades en la máquina virtual.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. Esto agrega tiempo de inicio innecesariamente y posiblemente al conjunto de trabajo (ya que algunas partes del árbol quizás nunca se hagan visibles).This adds unnecessarily to startup time and possibly to working set (because some parts of the tree may never become visible). Recomendaciones: usa los atributos x:Load o x:DeferLoadStrategy para diferir las partes innecesarias del árbol.Recommendations: Use the x:Load attribute or x:DeferLoadStrategy attribute feature to defer unnecessary portions of the tree out of startup. Además, crea controles de usuario separados para los diferentes modos de la página y usa el código subyacente para mantener cargados solo los controles necesarios.Also, create separate user controls for the different modes of the page and use code-behind to keep only the necessary controls loaded.

Recomendaciones para C++/CXC++/CX recommendations

  • Usa la versión más reciente.Use the latest version. Se presentan mejoras continuamente en el rendimiento del compilador de C++/CX.There are continual performance improvements made to the C++/CX compiler. Asegúrate de que crear tu aplicación con el conjunto de herramientas más reciente.Ensure your app is building using the latest toolset.
  • Deshabilita RTTI (/GR-) .Disable RTTI (/GR-). RTTI está activado de manera predeterminada en el compilador, por lo tanto, a menos que tu entorno de compilación lo desactiva, probablemente lo estés usando.RTTI is on by default in the compiler so, unless your build environment switches it off, you’re probably using it. RTTI tiene una sobrecarga significativa y, a menos que el código dependa mucho de él, deberías desactivarlo.RTTI has significant overhead, and unless your code has a deep dependency on it, you should turn it off. El marco de XAML no tiene ningún requisito que exige que tu código use RTTI.The XAML framework has no requirement that your code use RTTI.
  • Evita el uso elementos ppltasks intensivos.Avoid heavy use of ppltasks. Los elementos Ppltasks son muy convenientes cuando se llama a las API de WinRT asincrónicas, pero incluyen una sobrecarga significativa en relación con el tamaño del código.Ppltasks are very convenient when calling async WinRT APIs, but they come with significant code size overhead. El equipo de C++/CX está trabajando en una función del lenguaje (await) que proporcionará un rendimiento mucho mejor.The C++/CX team is working on a language feature – await – that will provide much better performance. Mientras tanto, equilibra el uso de los elementos ppltasks en las rutas de acceso activas del código.In the meantime, balance your use of ppltasks in the hot paths of your code.
  • Evita el uso de C++/CX en la "lógica de negocios" de la aplicación.Avoid use of C++/CX in the “business logic” of your app. C++/CX está diseñado para ofrecer una manera cómoda de acceder a las API de WinRT desde las aplicaciones C++.C++/CX is designed to be a convenient way to access WinRT APIs from C++ apps. Hace uso de contenedores que tienen sobrecarga.It makes use of wrappers that have overhead. Debes evitar el uso de C++/CX dentro de la lógica o modelo de negocio de tu clase y usarlo en los límites entre el código y WinRT.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.