经常绘制CGPath时的性能

And*_*ner 13 core-graphics objective-c cgpath ios

我正在开发一个将数据可视化为线图的iOS应用程序.该图表CGPath在全屏自定义中绘制UIView,最多包含320个数据点.数据经常更新,图表需要相应地重新绘制 - 刷新率为10 /秒会很好.

到目前为止这么容易.但是,我的方法似乎占用了大量的CPU时间.每秒10次刷新320个段的图形会导致iPhone 4S上的进程占CPU负载的45%.

也许我低估了引擎盖下的图形工作,但对我而言,CPU负载对于该任务似乎很重要.

下面是我的drawRect()函数,每次准备好一组新数据时都会调用它.N保持点的数量,并且points是具有CGPoint*要绘制的坐标的向量.

- (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); 
}
Run Code Online (Sandbox Code Playgroud)

我尝试首先将路径渲染到离线CGContext,然后按照此处的建议将其添加到当前层,但没有任何正面结果.我也直接向CALayer绘制了一个方法,但这也没有任何区别.

有关如何提高此任务性能的任何建议吗?或者渲染对我认识到的CPU更有用吗?OpenGL会有任何意义/差异吗?

谢谢/安迪

更新:我也尝试使用UIBezierPath而不是CGPath.这篇文章在这里给出了一个很好的解释为什么没有帮助.Tweaking CGContextSetMiterLimit等.也没有带来很大的解脱.

更新#2:我最终切换到OpenGL.这是一个陡峭而令人沮丧的学习曲线,但性能提升令人难以置信.但是,CoreGraphics的抗锯齿算法比OpenGL中的4x多重采样可以实现更好的工作.

Pet*_*sey 8

这篇文章在这里给出了一个很好的解释为什么没有帮助.

它还解释了为什么你的drawRect:方法很慢.

您每次绘制时都在创建一个CGPath对象.你不需要这样做; 每次修改点集时,只需要创建一个新的CGPath对象.将CGPath的创建移动到仅在点集更改时调用的新方法,并在对该方法的调用之间保留CGPath对象.有drawRect:简单的检索.

你已经发现渲染是你正在做的最昂贵的事情,这很好:你不能让渲染速度更快,是吗?实际上,除了渲染之外,drawRect:理想情况下应该做什么,所以你的目标应该是将尽可能接近渲染的时间推到100% - 这意味着尽可能地将所有其他内容移出绘图代码.


Tom*_*sen 5

根据创建路径的方式,可能是绘制300条单独的路径要比绘制300个点的一条路径快。这样做的原因是,绘图算法经常会寻找重叠的线,以及如何使交点看起来“完美”-当您可能只希望线彼此不透明地重叠时。许多重叠和相交算法的复杂度为N ** 2左右,因此绘制速度与一条路径中点数的平方成比例。

这取决于您使用的确切选项(其中一些默认)。您需要尝试一下。