SORU
13 HAZİRAN 2011, PAZARTESİ


Neden UİBezierPath daha hızlı Çekirdek Grafik yol daha mı?

Etrafında çizim yolları ile oynuyordum, ve düşündüm ki en azından bazı durumlarda, UİBezierPath geride Çekirdekli bir Grafik eşdeğer olacağını fark ettim. İki yol oluşturur altında -drawRect: yöntem: bir UİBezierPath ve bir CGPath. Kendi yolu üzerindeki yerler için de aynıdır, ama CGPath okşayarak yaklaşık iki kat daha uzun UİBezierPath okşayarak alır.

- (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];
}

Zaman Araçların her yolu tarafından kullanılan görebilmek inme için ayrı bir yöntem, her yol yarattım. her iki yol CGContextStrokePath kullanın(), Aşağıda tipik sonuçlarıdır (arama ağacı ters); -strokeContext: 9.5 aldığını görebilirsiniz sn. -strokeUIBezierPath: zaman alıyor sadece 5 sn.:

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:]

UİBezierPath bir şekilde oluşturduğu yolunu optimize gibi görünüyor, ya da naif bir şekilde CGPath yaratıyorum. Ben CGPath benim çizim hızlandırmak için ne yapabilirim?

CEVAP
15 HAZİRAN 2011, ÇARŞAMBA


UIBezierPath sadece objective-c sarıcı bir Çekirdek Grafikleri için bu doğru, ve bu nedenle nispeten bir konser verecek. Fark (ve performans delta nedeni) CGPath doğrudan çizim UIBezierPath kurulum için oldukça farklı olduğunda CGContext durumdur. Eğer UIBezierPath bakarsanız ayarları vardır:

  • lineWidth,
  • lineJoinStyle,
  • lineCapStyle,
  • miterLimit
  • flatness

[path stroke], çağrı (söküm) incelerken CGContextStrokePath arama yapmadan önce önceki değerlere göre geçerli grafik içerik yapılandırır unutmayın. Eğer CGPath çizim önce aynı şeyi yaparsan, aynısını gerçekleştirir:

- (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];
}

Araçlardan anlık: Instruments snapshot showing equal performance

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Chuck Testa

    Chuck Testa

    14 AĞUSTOS 2011
  • rtisticsdev

    rtisticsdev

    31 Mayıs 2012
  • Showtime

    Showtime

    21 HAZİRAN 2006