Estoy trabajando en una aplicación de iOS que visualiza los datos como un gráfico de líneas. El gráfico se dibuja como CGPath
en una pantalla completa personalizada UIView
y contiene como máximo 320 puntos de datos. Los datos se actualizan con frecuencia y el gráfico debe volverse a dibujar en consecuencia; una frecuencia de actualización de 10 por segundo sería agradable.Rendimiento al dibujar CGPaths con frecuencia
Hasta ahora, tan fácil. Parece, sin embargo, que mi enfoque requiere mucho tiempo de CPU. Actualizar el gráfico con 320 segmentos a 10 veces por segundo da como resultado una carga de CPU del 45% para el proceso en un iPhone 4S.
Tal vez subestimo el trabajo de gráficos bajo el capó, pero para mí la carga de la CPU parece mucho para esa tarea.
A continuación se muestra la función drawRect()
que recibe llamadas cada vez que un nuevo conjunto de datos está listo. N
tiene el número de puntos y points
es un vector CGPoint*
con las coordenadas para dibujar.
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
// set attributes
CGContextSetStrokeColorWithColor(context, [UIColor lightGrayColor].CGColor);
CGContextSetLineWidth(context, 1.f);
// create path
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddLines(path, NULL, points, N+1);
// stroke path
CGContextAddPath(context, path);
CGContextStrokePath(context);
// clean up
CGPathRelease(path);
}
he intentado hacer que la ruta de acceso a una línea CGContext primero antes de añadir a la capa actual como se sugiere here, pero sin ningún resultado positivo. También jugueteé con un dibujo de aproximación al CALayer directamente, pero eso tampoco importó.
¿Alguna sugerencia de cómo mejorar el rendimiento para esta tarea? ¿O es que la representación simplemente más trabajo para la CPU que me doy cuenta? ¿OpenGL tendría algún sentido/diferencia?
Gracias/Andi
Actualización: también trató de usar UIBezierPath
en lugar de CGPath
. Esta publicación here da una buena explicación de por qué eso no ayudó. Afinando CGContextSetMiterLimit
y col. tampoco trajo un gran alivio.
Actualización n. ° 2: Finalmente cambié a OpenGL. Fue una curva de aprendizaje empinada y frustrante, pero el aumento en el rendimiento es simplemente increíble. Sin embargo, los algoritmos anti-aliasing de CoreGraphics hacen un trabajo mejor que el que se puede lograr con 4x-multisampling en OpenGL.
Su color es una constante. Muévelo si drawRect y sigue reutilizándolo en lugar de pedir uno nuevo cada vez. Lo mismo para el camino. Como StrokePath() "vacía la ruta", puede reutilizar el mismo objeto de ruta una y otra vez. ¿Qué cambia eso? – verec
La documentación dice que la ruta está vacía, pero al menos en mi código no lo está. Simplemente sigue creciendo. En cuanto al color, tienes un punto. Eso fue malo, pero no la solución. Gracias. –
Te refieres a UIBezierPath, ¿verdad? NSBezierPath solo existe en la Mac. –