【发布时间】:2012-01-03 16:57:59
【问题描述】:
我正在开发一个将数据可视化为折线图的 iOS 应用程序。该图在全屏自定义UIView 中绘制为CGPath,最多包含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);
}
我尝试先渲染离线 CGContext 的路径,然后按照建议 here 将其添加到当前层,但没有任何积极的结果。我还摆弄了一种直接绘制到 CALayer 的方法,但这也没什么区别。
有什么建议可以提高这项任务的性能吗?还是我意识到,渲染对 CPU 的工作量更大? OpenGL 有什么意义/区别吗?
谢谢/安迪
更新:我也尝试使用UIBezierPath 而不是CGPath。这篇文章here 很好地解释了为什么这没有帮助。调整CGContextSetMiterLimit 等。也没有带来很大的缓解。
更新 #2:我最终切换到了 OpenGL。这是一个陡峭而令人沮丧的学习曲线,但性能提升令人难以置信。但是,CoreGraphics 的抗锯齿算法比 OpenGL 中的 4 倍多重采样做得更好。
【问题讨论】:
-
你的颜色是一个常数。如果 drawRect 将其移出并继续重用它,而不是每次都要求一个新的。路径同上。由于 StrokePath() “清空路径”,您可以一遍又一遍地重用相同的路径对象。这有什么变化?
-
文档声称路径已清空,但至少在我的代码中没有。它只是不断增长。至于颜色,你有道理。那很糟糕,但不是解决方案。谢谢。
-
你的意思是 UIBezierPath,对吧? NSBezierPath 仅存在于 Mac 上。
-
我愿意。谢谢。相应地编辑了帖子。
-
这里有同样的问题。在我看来,Apple 在 iOS 上的 CGPath 实现非常缓慢 - 一旦超过 20-30 条路径,性能就会直线下降......完全没有理由。相同的硬件,相同的数据集,如果我在 OpenGL 中进行粗制滥造的重新实现,我将获得 20 倍的性能。我不知道苹果在做什么,但这似乎是非常错误的:(。
标签: objective-c ios core-graphics cgpath