Estaba jugando con las rutas de dibujo, y noté que en al menos algunos casos, UIBezierPath supera lo que pensé que sería un equivalente de Core Graphics. El siguiente método -drawRect:
crea dos rutas: una UIBezierPath y una CGPath. Los caminos son idénticos, excepto por su ubicación, pero acariciar el CGPath toma aproximadamente el doble de tiempo que acariciar el UIBezierPath.¿Por qué UIBezierPath es más rápido que la ruta de Core Graphics?
- (void)drawRect:(CGRect)rect
{
CGContextRef ctx = UIGraphicsGetCurrentContext();
// Create the two paths, cgpath and uipath.
CGMutablePathRef cgpath = CGPathCreateMutable();
CGPathMoveToPoint(cgpath, NULL, 0, 100);
UIBezierPath *uipath = [[UIBezierPath alloc] init];
[uipath moveToPoint:CGPointMake(0, 200)];
// Add 200 curve segments to each path.
int iterations = 200;
CGFloat cgBaseline = 100;
CGFloat uiBaseline = 200;
CGFloat xincrement = self.bounds.size.width/iterations;
for (CGFloat x1 = 0, x2 = xincrement;
x2 < self.bounds.size.width;
x1 = x2, x2 += xincrement)
{
CGPathAddCurveToPoint(cgpath, NULL, x1, cgBaseline-50, x2, cgBaseline+50, x2, cgBaseline);
[uipath addCurveToPoint:CGPointMake(x2, uiBaseline)
controlPoint1:CGPointMake(x1, uiBaseline-50)
controlPoint2:CGPointMake(x2, uiBaseline+50)];
}
[[UIColor blackColor] setStroke];
CGContextAddPath(ctx, cgpath);
// Stroke each path.
[self strokeContext:ctx];
[self strokeUIBezierPath:uipath];
[uipath release];
CGPathRelease(cgpath);
}
- (void)strokeContext:(CGContextRef)context
{
CGContextStrokePath(context);
}
- (void)strokeUIBezierPath:(UIBezierPath*)path
{
[path stroke];
}
Ambos caminos utilizan CGContextStrokePath(), por lo que crea métodos separados a un accidente cerebrovascular cada trayectoria de modo que pueda ver el tiempo utilizado por cada trayectoria de un instrumento. A continuación se muestran los resultados típicos (árbol de llamadas invertidas); se puede ver que lleva -strokeContext:
9,5 seg., mientras que -strokeUIBezierPath:
tarda sólo 5 seg .:
Running (Self) Symbol Name
14638.0ms 88.2% CGContextStrokePath
9587.0ms 57.8% -[QuartzTestView strokeContext:]
5051.0ms 30.4% -[UIBezierPath stroke]
5051.0ms 30.4% -[QuartzTestView strokeUIBezierPath:]
Parece que UIBezierPath es de alguna manera la optimización de la ruta que se crea, o estoy creando el CGPath de una manera ingenua. ¿Qué puedo hacer para acelerar mi dibujo de CGPath?
1 que suena contra-intutive. –
En general, he encontrado que CoreGraphics es muy lento al dibujar líneas, caminos, etcétera. No tengo idea de por qué, pero la mayoría de las veces tengo que ir a OpenGL o usar Cocos2D para un dibujo eficiente. Claro que entiendo que es más rápido, pero realmente no entiendo por qué CG es mucho más lento, considerando que debería usar OpenGL. – Accatyyc
'UIBezierPath' es un contenedor alrededor de' CGPathRef'. ¿Qué pasa si ejecuta ambos, digamos, diez millones de veces, y luego toma el promedio, pero no utiliza instrumentos sino dos objetos 'NSDate' antes y después de las operaciones. –