2011-01-31 18 views
5

Estoy dibujando un montón de líneas en un lienzo largo (creo stripchart) y lo ajuste bastante bien para el rendimiento, utilizando las clases de geometría de bajo nivel y la congelación, etc. Esto mejoró dramáticamente el rendimiento, pero aún lleva unos segundos cargar algunos miles de elementos en el lienzo. Ejecuté un análisis de rendimiento en la aplicación, y parece que un gran porcentaje del tiempo lo toma cada llamada al canvas.children.add(). He leído que esto debería ser una llamada ligera, y como la estoy llamando varias veces en un método, no debería tratar de hacer algo pesado entre ellos ... ¿Podría haber alguna otra razón por la que esto podría estar tomando? ¿mucho tiempo? ¿Y de alguna manera podría acelerarlo?WPF lienzo rendimiento- children.add llamado muchas veces

El rendimiento no es terrible, pero me temo que podría convertirse en un problema más adelante cuando necesite manejar conjuntos más grandes de datos.

Solo como referencia, parece que se llama 1400 veces en esta muestra y tarda casi 3 segundos de tiempo de CPU en una computadora portátil moderna/rápida.

El lienzo está contenido en una jerarquía de otros controles, por lo que tengo curiosidad de si podrían estar contribuyendo a esto.

Nota adicional: tampoco estoy estableciendo una altura específica en el lienzo, ya que está configurado para llenar el contenedor padre de la cuadrícula. ¿Podría ser esto una fuente de problemas?

+2

En lo que respecta al rendimiento, puede intentar http : //msdn.microsoft.com/en-us/library/system.windows.media.streamgeometry.aspx Stream Geometry, que es la construcción más ligera que el contexto de dibujo. –

+0

sí, ya está usando la geometría del flujo y con buenos resultados. gracias –

Respuesta

0

Le sugiero que dibuje sus formas directamente en una imagen en lugar de agregarlas de niños. El renderizado de niños tiene una sobrecarga ENORME (como se puede ver).

Hay una pregunta similar con una referencia a algunos artículos útiles:

How to draw line of ten thousands of points with WPF within 0.5 second?

+0

Estaba esperando evitar esto, ya que tengo otras cosas en juego que pueden hacer que sea complicado volver a dibujar siempre. como cuadros de texto e imágenes añadidos en la parte superior que se pueden arrastrar, y la sección es muy larga, por lo que existe en un contenedor desplazable. Muchas variables a considerar ... –

+3

Dependiendo de cuán crítico sea el rendimiento para usted, es posible que desee considerar una solución en uno de los muchos marcos de juego en C# (es decir, algo que manipule los sprites). Por supuesto, si también desea utilizar otro mecanismo de UI Framework que realmente no lo ayudará ... BTW: Bajo ciertas condiciones, WPF no usará procesamiento de hardware, lo que puede reducir drásticamente el rendimiento. Puede verificarlo con este método ' Debug.WriteLine ("WPF RenderCapabilities: Rendering Tier =" + (RenderCapability.Tier >> 16) + "(Deseado 2, 0 Significa que no hay aceleración de hardware)"); ' – NightDweller

1

sólo para añadir acerca de la jerarquía de los controles de la tela está dentro, y la altura del lienzo:

la El lienzo siempre ocupa tanto espacio como se le da, y no importa qué niños le agreguen, NUNCA desencadena un nuevo Measuer/Arrange pasa a sus padres. por lo tanto, lo que sea que haga dentro de un lienzo nunca podría afectar el árbol visual en el que está contenido. Para resumir, el problema no puede provenir de allí, y la sugerencia sobre StreamGeomatry es correcta, esto es lo que le está causando los problemas de rendimiento. y cambiar a streamgeormatry lo resolvería.

+0

Ya estoy usando streamgeometry para todos los niños agregados aplicables. ayudaron mucho al rendimiento, pero aún buscan mejorar sustancialmente. –

+1

me hizo un mentiroso, en realidad terminé usando la patogenometría en algún momento. Acaba de convertirse a streamgeo y definitivamente es más rápido. –

+0

-1 porque tengo el mismo problema, pero, estoy tratando con niños de tipo Shapes, y tengo el mismo comportamiento lento – simo

4

El principal problema es que Children.Add siempre es una operación lenta, incluso si usa objetos StreamGeometry. Me enfrenté al mismo problema recientemente y concluí lo siguiente: Si coloca un grupo de objetos en un nuevo lienzo y lo anida en el lienzo principal, el rendimiento de la operación de adición aumentará drásticamente. Por lo tanto, en lugar de agregar 1400 elementos, coloque 200 elementos en 7 lienzos y agregue esos 7 lienzos al lienzo principal. Dado que todos los objetos ahora pertenecen a diferentes lienzos, tendrá que ajustar su aplicación un poco, pero esto sería una solución menos drástica que pasar a una solución alternativa como DrawingVisual

+0

Jaime, ¿qué tan grande de ganancia de rendimiento estimaría de esto? es decir, 10% o 100% de ganancia de velocidad? Gracias. –

+0

En mi caso específico (300 objetos añadidos al mismo tiempo en una colección de 5000+ niños), tuve un retraso de 2.5 segundos y me convertí en 0.3 segundos. –

+0

wow eso es realmente bueno. gracias de nuevo. –

Cuestiones relacionadas