UIBeezierPath가 코어 그래픽 경로보다 빠른 이유는 무엇입니까?
도면 경로를 가지고 놀다가 적어도 어떤 경우에는 UIBizierPath가 코어 그래픽스와 동등하다고 생각했던 것보다 성능이 우수하다는 것을 알게 되었습니다.-drawRect:
아래 메소드는 두 개의 경로, 즉 하나의 UIBizerPath와 하나의 CGPath를 생성합니다.경로는 위치를 제외하고는 동일하지만 CGP 경로를 사용하는 것이 UIBeezier 경로를 사용하는 것보다 약 2배 더 오래 걸립니다.
- (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];
}
두 경로 모두 CGC ContextStrokePath()를 사용하므로 Instruments에서 각 경로가 사용하는 시간을 볼 수 있도록 각 경로를 스트로크하는 별도의 메서드를 만들었습니다.아래는 일반적인 결과(콜 트리 반전)입니다. 다음을 확인할 수 있습니다.-strokeContext:
9.5초가 소요되는 반면,-strokeUIBezierPath:
5초 밖에 걸리지 않습니다.:
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:]
UIBeezierPath가 생성하는 경로를 최적화하는 것처럼 보이거나 CGPath를 순진하게 만들고 있습니다.CGPath 그리기 속도를 높이려면 어떻게 해야 합니까?
그것은 당신이 옳습니다.UIBezierPath
는 단순히 코어 그래픽스용 목적 c 래퍼이며, 따라서 비슷한 성능을 발휘합니다.차이(및 성능 델타의 이유)는CGContext
그림을 그릴 때 상태CGPath
직접적으로 설정과 상당히 다릅니다.UIBezierPath
을 보면UIBezierPath
다음에 대한 설정이 있습니다.
lineWidth
,lineJoinStyle
,lineCapStyle
,miterLimit
그리고.flatness
통화(분해)를 검토할 때[path stroke]
다음을 수행하기 전에 이전 값을 기반으로 현재 그래픽 컨텍스트를 구성합니다.CGContextStrokePath
CGP 경로를 그리기 전에 동일한 작업을 수행하면 다음과 같이 수행됩니다.
- (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 = 80000;
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
CGContextSaveGState(ctx); {
// configure context the same as uipath
CGContextSetLineWidth(ctx, uipath.lineWidth);
CGContextSetLineJoin(ctx, uipath.lineJoinStyle);
CGContextSetLineCap(ctx, uipath.lineCapStyle);
CGContextSetMiterLimit(ctx, uipath.miterLimit);
CGContextSetFlatness(ctx, uipath.flatness);
[self strokeContext:ctx];
CGContextRestoreGState(ctx);
}
[self strokeUIBezierPath:uipath];
[uipath release];
CGPathRelease(cgpath);
}
- (void)strokeContext:(CGContextRef)context
{
CGContextStrokePath(context);
}
- (void)strokeUIBezierPath:(UIBezierPath*)path
{
[path stroke];
}
계측기에서 스냅샷:
언급URL : https://stackoverflow.com/questions/6327817/why-is-uibezierpath-faster-than-core-graphics-path
'programing' 카테고리의 다른 글
이전 활동으로 돌아가는 것을 방지하는 방법은 무엇입니까? (0) | 2023.08.05 |
---|---|
T-SQL, SQL Server 및 SQL의 차이점은 무엇입니까? (0) | 2023.08.05 |
PowerShell의 UTF8 스크립트가 잘못된 문자를 출력함 (0) | 2023.08.05 |
configurationManager가 네임스페이스 시스템에 없습니다.배열 (0) | 2023.08.05 |
데스크톱으로의 경로에 대한 환경 변수는 무엇입니까? (0) | 2023.08.05 |