ইউআইবিজেয়ারপথ কেন কোর গ্রাফিক্সের চেয়ে দ্রুত?


90

আমি অঙ্কনের পথগুলি নিয়ে ঘুরে বেড়াচ্ছিলাম এবং আমি লক্ষ্য করেছি যে কমপক্ষে কিছু ক্ষেত্রে ইউআইবিজেয়ারপথটি আমি যা কোর গ্রাফিক্সের সমতুল্য বলে বিবেচনা করেছিলাম তা ছাড়িয়ে যায়। -drawRect:এক UIBezierPath, এবং CGPath: নীচের পদ্ধতি দু পাথ তৈরি করে। পাথগুলি তাদের অবস্থানগুলি ব্যতীত অভিন্ন, তবে সিজিপিথকে স্ট্রোক করতে ইউআইবেজারপথ স্ট্রোক করতে প্রায় দ্বিগুণ সময় লাগে।

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

উভয় পাথই সিজি কনটেক্সটস্ট্রোকপথ () ব্যবহার করে, তাই আমি প্রতিটি পাথ স্ট্রোক করার জন্য পৃথক পদ্ধতি তৈরি করেছি যাতে আমি ইনস্ট্রুমেন্টগুলির প্রতিটি পাথের জন্য ব্যবহৃত সময়টি দেখতে পারি। নীচে সাধারণ ফলাফল রয়েছে (কল ট্রি ইনভার্টেড); আপনি দেখতে পাচ্ছেন যে -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:]

দেখে মনে হচ্ছে ইউআইবিজেয়ারপথটি যেভাবে এটি তৈরি করে তার পথটি অনুকূল করে তুলছে, বা আমি সিজিপিথকে নির্লজ্জভাবে তৈরি করছি। আমার সিজিপিথ অঙ্কনের গতি বাড়ানোর জন্য আমি কী করতে পারি?


4
+1 যা উত্তেজনাপূর্ণ শোনায়।
গ্রেডি প্লেয়ার

4
আমি সাধারণত লাইন, পথ ইত্যাদির অঙ্কন করার সময় কোরিগ্রাফিকগুলি খুব ধীর হতে দেখেছি। তবে আমার বেশিরভাগ ক্ষেত্রেই আমাকে ওপেনজিএলে যেতে হবে বা দক্ষ অঙ্কনের জন্য কোকোস 2 ডি ব্যবহার করতে হবে তা সম্পর্কে আমার কোনও ধারণা নেই। অবশ্যই আমি বুঝতে পেরেছি যে এটি দ্রুত, তবে সিজি কেন এত বেশি ধীর হয় তা আমি সত্যিই বুঝতে পারি না, এটি বিবেচনা করে এটিকে ওপেনজিএল ব্যবহার করা উচিত।
অ্যাকাটাইক

4
UIBezierPathচারপাশে একটি মোড়ক হয় CGPathRef। আপনি যদি উভয়ই চালান তবে দশ মিলিয়ন বার বলা যাক, তবে গড় গ্রহণ করুন, তবে NSDateঅপারেশনগুলির আগে এবং পরে দুটি উপকরণ ছাড়া দুটি উপকরণ ব্যবহার করবেন না ।

4
@ ডাব্লুটিপি, ফলাফলগুলি ডিভাইস এবং সিমুলেটেয়ারের সাথে সামঞ্জস্যপূর্ণ এবং -drawRect:কয়েক ডজন বার বলা হয় বা কয়েক শতাধিক বলা হোক না কেন পরিবর্তন হয় না । আমি সিমুলেটারে প্রায় 80000 কার্ভ সেগমেন্টের সাহায্যে এটি চেষ্টা করেছি (ডিভাইসের পক্ষে অনেক বেশি)। ফলাফলগুলি সর্বদা একইরকম: সিজিপিথ ইউআইবিজেয়ারপথের দ্বিগুণ দীর্ঘ সময় নেয়, যদিও উভয়ই আঁকতে সিজি কনটেক্সটস্ট্রোকপথ () ব্যবহার করে। এটি স্পষ্ট বলে মনে হয় যে ইউআইবিজেয়ারপথটি যে পথটি তৈরি করেছে তা আমি সিজিপিথএডকুরিভটুইপয়েন্ট () দিয়ে তৈরি করি তার চেয়ে একরকম কার্যকর। আমি ইউআইবিজেয়ারপথের মতো দক্ষ পথগুলি কীভাবে তৈরি করব তা জানতে চাই।
কালেব

উত্তর:


154

আপনি যে UIBezierPathসঠিকভাবে কোর গ্রাফিক্সের জন্য একটি উদ্দেশ্য-সি মোড়ক হিসাবে সঠিক , এবং সুতরাং তুলনামূলক সম্পাদন করবে। CGContextআপনার CGPathসরাসরি অঙ্কন করার সময় পার্থক্য (এবং আপনার পারফরম্যান্স ডেল্টার কারণ) আপনার রাজ্যটি সেই সেটআপের থেকে একেবারেই আলাদা UIBezierPath। আপনি যদি তাকান UIBezierPath, এটির জন্য সেটিংস রয়েছে:

  • lineWidth,
  • lineJoinStyle,
  • lineCapStyle,
  • miterLimit এবং
  • flatness

এতে কলটি (বিচ্ছিন্ন) পরীক্ষা করার সময় [path stroke]আপনি লক্ষ্য করবেন যে এটি CGContextStrokePathকল করার আগে পূর্ববর্তী মানগুলির উপর ভিত্তি করে বর্তমান গ্রাফিক প্রসঙ্গটি কনফিগার করে । আপনি যদি নিজের সিজিপিথ আঁকার আগে একই কাজ করেন তবে এটি একই সম্পাদন করবে:

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

যন্ত্রপাতি থেকে স্ন্যাপশট: ইন্সট্রুমেন্টস স্ন্যাপশট সমান পারফরম্যান্স দেখায়


6
এটি সন্ধান করার জন্য সময় দেওয়ার জন্য এবং এরকম একটি পরিষ্কার ব্যাখ্যা লেখার জন্য ধন্যবাদ। এটি সত্যিই একটি দুর্দান্ত উত্তর।
কালেব

14
আটারি ব্রুস লি আইকনের জন্য +1 ... এবং সম্ভবত উত্তরের জন্য।
গ্রেডি প্লেয়ার

4
সুতরাং ... 2x পারফরম্যান্স পার্থক্যটি সিগকন্টেক্সট সেটিংসের এক বা একাধিক ছিল - উদাহরণস্বরূপ এমন কিছু হতে পারে: "২.০ এর লাইনউইথটি ০.০ এর লাইনউইথের চেয়েও খারাপ সম্পাদন করে" ...?
অ্যাডাম

4
এফডাব্লুআইডাব্লু আমি সর্বদা দ্রুততম হতে 1.0 এর লাইনের প্রস্থ খুঁজে পেয়েছি - আমার ধারণাটি হ'ল প্রশমিতকরণ প্রস্থ> 1px এর জন্য একটি ইস্যুতে পরিণত হয়।
মার্ক অফলিক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.