Optimizing XamDataGrid Performance Using External Data Operations
Una serie de aplicaciones de línea de negocio usan XamDataGrid por su amplio conjunto de características, alta personalización y rendimiento.
Si ha habido un desarrollo constante en el uso de XamDataGrid en todos los sectores, ha sido la creciente cantidad de datos que se muestran en XamDataGrid. Tradicionalmente, los controles de cuadrícula realizan operaciones de datos como ordenar, filtrar y agrupar por sí mismos en el subproceso de la interfaz de usuario. Sin embargo, con el aumento de las cargas de datos, los desarrolladores buscan formas de realizar estas operaciones en un subproceso independiente o en un equipo completamente diferente. Esta es la razón por la que los desarrolladores nos han pedido que XamDataGrid pase los argumentos de estas operaciones y, sin realizar esta operación, que muestre el resultado procesado. Hemos agregado esta funcionalidad en la versión 12.1 y nos ha permitido mejorar significativamente el rendimiento cuando grandes conjuntos de datos están enlazados a XamDataGrid. En esta entrada de blog se describe cómo aprovechar esta funcionalidad y sus implicaciones para el rendimiento en términos de superficie de memoria y tiempo que se tarda en realizar una operación.
Descargue el proyecto de ejemplo: muestra cómo activar el procesamiento fuera de la red de manipulaciones de datos y compara el rendimiento de un XamDataGrid enlazado al mismo conjunto de datos en los dos casos, cuando se usan operaciones internas y externas. El proyecto se ha creado con Visual Studio 2010 y .NET Framework 4. Usa una versión de prueba del producto WPF 12.1, por lo que puede compilarlo y ejecutarlo sin ninguna descarga adicional. Está disponible una versión de prueba gratuita de 30 días totalmente funcional del producto NetAdvantage para WPF, que incluye XamDataGrid. Esta es una captura de pantalla del proyecto de ejemplo:

¿Qué hay en la muestra?
En la aplicación de ejemplo, hay dos XamDataGrids uno al lado del otro: el de la izquierda usa operaciones internas y el de la derecha realiza estas operaciones a través del objeto CollectionView en su lugar. Ambas cuadrículas están enlazadas a un conjunto de datos que contiene 100.000 registros. Para ilustrar la diferencia de rendimiento debido a operaciones internas o externas, compararemos el rendimiento de la ordenación y la agrupación. Sin embargo, exactamente los mismos resultados también se aplicarían al filtrado y a los cálculos de resumen.
Implicaciones para el rendimiento del uso de ordenación/grupo interno
De forma predeterminada, XamDataGrid solo crea objetos de registro para representar los elementos de datos que están visibles actualmente (en lugar de todos los registros del conjunto de datos). Sin embargo, cuando XamDataGrid realiza internamente operaciones de ordenación o agrupación, necesita crear objetos de registro para representar todos los elementos del conjunto de datos, de modo que pueda ordenarlos o agruparlos. Aunque los elementos de la interfaz de usuario no se crean para todos estos registros debido a la lógica de virtualización de la interfaz de usuario de XamDataGrid, los objetos de registro pueden tener un impacto sustancial en la superficie de memoria de la aplicación (como veremos en la comparación de rendimiento a continuación), especialmente cuando los conjuntos de datos enlazados a XamDataGrid son grandes. Entonces, ¿cómo afecta esto al rendimiento? La primera vez que un usuario ordena o agrupa una cuadrícula, hay un retraso durante el cual XamDataGrid crea objetos de registro para todos los elementos de datos y, a continuación, realiza la operación solicitada por el usuario. Esto coloca todo el conjunto de datos en la memoria en términos de objetos de registro administrados por XamDataGrid. Si bien esto aumenta la superficie de memoria y provoca un retraso la primera vez que se ejecuta una operación de este tipo, las operaciones de ordenación/grupo posteriores son bastante rápidas, ya que todo el conjunto de datos ya está en la memoria.
Veamos cómo afecta esto al rendimiento. Ejecute el ejemplo y ordene o agrupe el XamDataGrida la izquierda: verá el cambio de tiempo y memoria (delta) informado sobre él. En mi máquina, cuando la cuadrícula de operaciones interna se ordena por primera vez, la operación tarda 4,3 segundos y el consumo de memoria aumenta en 40 MB. Las ordenaciones posteriores tardan alrededor de 1 segundo y la huella de memoria permanece igual (ya que ya está en su máximo: todos los elementos de datos se representan como objetos de registro). Una vez que el conjunto de datos ya está completamente cargado, la agrupación tarda unos 2,8 segundos y la desagrupación 1,2 segundos.
Implicaciones en el rendimiento del uso de ordenación/grupo externo
Puede controlar cómo se realizan los cálculos de ordenación, agrupación, filtrado y resumen mediante las propiedades SortEvaluationMode,GroupByEvaluationMode,FilterEvaluationMode y SummaryEvaluationMode. Ofrecen la capacidad de deshabilitar los cálculos internos de ordenación, agrupación, filtrado y resumen, y de realizar manualmente o a través del objeto CollectionView. Esto significa que la cuadrícula no tiene que inicializar los objetos de registro para representar todo el conjunto de datos, sino que depende del backend para reordenar el conjunto de datos. En el caso de usar la vista de colección (estableciendo las propiedades anteriores en "UseCollectionView"), esto no requiere ninguna implementación de lógica adicional. Sin embargo, si tiene un servidor backend, donde se realizan cálculos/reordenamientos, puede usar la configuración Manual para las propiedades anteriores. Esto hará que XamDataGrid desencadene los eventos Sorting / Grouping / RecordFilterChanging, lo que le permitirá pasarlos al back-end, donde se realizan los cálculos. XamDataGrid mostrará el conjunto de datos reordenado una vez que el back-end lo haya procesado.
El uso de la configuración UseCollectionView y Manual para la ordenación o agrupación ahorra a XamDataGrid la necesidad de crear instancias de objetos de registro para todo el conjunto de datos, lo que mantiene la superficie de memoria constantemente baja. El componente de tiempo del rendimiento depende del back-end que esté usando para el procesamiento de estas operaciones. En este ejemplo, en XamDataGrida la derecha, usamos el objeto CollectionView para controlar estas operaciones en lugar de la lógica interna.
¿Qué hay del rendimiento en este caso? Ejecute el ejemplo y ordene o agrupe XamDataGrida la derecha: el cambio de tiempo y superficie de memoria se informará justo arriba. Cuando collectionView realiza la ordenación y la agrupación (mediante el valor de UseCollectionView para las propiedades SortEvaluationMode y GroupByEvaluationMode), la superficie de memoria permanece igual y el tiempo que tarda es el siguiente: ordenar 2,5 segundos, agrupar 4,9 segundos y desagrupar 2,5 segundos. Hay tres puntos a mencionar aquí:
1. La superficie de memoria permanece constante, ya que no se crean instancias de objetos de registro adicionales debido a la ordenación/agrupación
2. El tiempo que se tarda en ordenar/agrupar es constante, es decir, no hay un retraso significativo al realizar la primera ordenación/grupo (como es el caso cuando se utilizan operaciones internas, debido a la inicialización de objetos de registro)
3. El tiempo que se tarda en ordenar/agrupar es mayor que el tiempo que se tarda en realizar las mismas operaciones si se utilizan operaciones internas. Sin embargo, el aspecto temporal del rendimiento depende completamente del backend que desee usar para estas operaciones. Aun así, el uso de los objetos collectionView proporciona un bajo consumo de memoria y un buen rendimiento de ordenación/grupo por primera vez (mientras que en el caso de las operaciones internas tiene un retraso adicional la primera vez que se realiza una operación) y puede ser útil en algunos casos.
Summary Calculations
Los cálculos de resumen internos predeterminados requieren que la cuadrícula inicialice los objetos de registro para representar todo el conjunto de datos. Con la propiedad SummaryEvaluationMode, los cálculos de resumen también se pueden realizar mediante Linq o manualmente. Aunque el uso de Linq no requiere ninguna implementación adicional por su parte, el uso del modo de cálculo manual requiere el control del evento QuerySummaryResult, donde puede realizar su propia lógica de evaluación y proporcionar un valor para el resultado de resumen. El uso del modo manual le permite mantener bajo el consumo de memoria y le brinda la oportunidad de mejorar el tiempo de cálculo tanto como pueda optimizando el backend.
Resumen
En esta entrada de blog, presenté cómo configurar XamDataGrid para realizar cálculos de ordenación/agrupación/filtrado/resumen externamente. Describimos la API que se usará para este propósito y analizamos las implicaciones de rendimiento del uso de operaciones externas. El proyecto de ejemplo se puede usar para demostrar fácilmente la diferencia entre los dos escenarios y se puede cambiar fácilmente para que pueda ver la mejora en el rendimiento que vería al enlazar sus propios datos a él. Con el modo manual, esencialmente puede eliminar cualquier limitación en la clasificación/agrupación/filtrado/resúmenes impuesta hasta ahora por el hardware de la máquina cliente que ejecuta su aplicación: el uso de máquinas backend de cálculo potentes es la mejor manera de procesar grandes conjuntos de datos de manera eficiente, al tiempo que ofrece una interfaz de usuario rápida y receptiva. Puede empezar por hablar con los usuarios de sus aplicaciones y conocer las vistas en las que se beneficiarían de que se mostraran mayores cantidades de datos para ayudarles a tomar una decisión. Una vez que los conozca, XamDataGrid le ayudará a satisfacer el creciente apetito de sus usuarios por mostrar más datos, al tiempo que ofrece una excelente experiencia de usuario.