经常绘制CGPath时的性能 [英] Performance when frequently drawing CGPaths

查看:78
本文介绍了经常绘制CGPath时的性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am working on an iOS App that visualizes data as a line-graph. The graph is drawn as a CGPath in a fullscreen custom UIView and contains at most 320 data-points. The data is frequently updated and the graph needs to be redrawn accordingly – a refresh rate of 10/sec would be nice.

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

So far so easy. It seems however, that my approach takes a lot of CPU time. Refreshing the graph with 320 segments at 10 times per second results in 45% CPU load for the process on an iPhone 4S.

也许我低估了引擎盖下的图形工作,但对我来说,这个任务的CPU负载似乎很多。

Maybe I underestimate the graphics-work under the hood, but to me the CPU load seems a lot for that task.

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

Below is my drawRect() function that gets called each time a new set of data is ready. N holds the number of points and points is a CGPoint* vector with the coordinates to draw.

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

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

I tried rendering the path to an offline CGContext first before adding it to the current layer as suggested here, but without any positive result. I also fiddled with an approach drawing to the CALayer directly but that too made no difference.

有关如何提高此任务性能的任何建议吗?或者渲染对于我意识到的CPU来说更加有用吗? OpenGL会有什么意义/区别吗?

Any suggestions how to improve performance for this task? Or is the rendering simply more work for the CPU that I realize? Would OpenGL make any sense/difference?

谢谢/ Andi

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

Update: I also tried using UIBezierPath instead of CGPath. This post here gives a nice explanation why that didn't help. Tweaking CGContextSetMiterLimit et al. also didn't bring great relief.

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

Update #2: I eventually switched to OpenGL. It was a steep and frustrating learning curve, but the performance boost is just incredible. However, CoreGraphics' anti-aliasing algorithms do a nicer job than what can be achieved with 4x-multisampling in OpenGL.

推荐答案


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

This post here gives a nice explanation why that didn't help.

这也解释了为什么你的 drawRect:方法很慢。

It also explains why your drawRect: method is slow.

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

You're creating a CGPath object every time you draw. You don't need to do that; you only need to create a new CGPath object every time you modify the set of points. Move the creation of the CGPath to a new method that you call only when the set of points changes, and keep the CGPath object around between calls to that method. Have drawRect: simply retrieve it.

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

You already found that rendering is the most expensive thing you're doing, which is good: You can't make rendering faster, can you? Indeed, drawRect: should ideally do nothing but rendering, so your goal should be to drive the time spent rendering as close as possible to 100%—which means moving everything else, as much as possible, out of drawing code.

这篇关于经常绘制CGPath时的性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆