jjzjj

objective-c - 频繁绘制 CGPath 时的性能

coder 2023-07-27 原文

我正在开发一款将数据可视化为折线图的 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 倍多重采样可以实现的效果更好。

最佳答案

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

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

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

您已经发现渲染是您正在做的最昂贵的事情,这很好:您不能让渲染更快,不是吗?实际上,drawRect: 理想情况下应该除了 渲染之外什么都不做,因此您的目标应该是使渲染时间尽可能接近 100%——这意味着移动其他一切,尽可能多地退出绘图代码。

关于objective-c - 频繁绘制 CGPath 时的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8715749/

有关objective-c - 频繁绘制 CGPath 时的性能的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  3. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  4. ruby-on-rails - 如何从过时的 TZInfo 标识符中获取 Rails TimeZone 名称? - 2

    已经有一个问题回答了如何将“America/Los_Angeles”转换为“PacificTime(US&Canada)”。但是我想将“美国/太平洋”和其他过时的时区转换为RailsTimeZone。我无法在图书馆中找到任何可以帮助我完成此任务的东西。 最佳答案 来自RailsActiveSupport::TimeZonedocs:TheversionofTZInfobundledwithActiveSupportonlyincludesthedefinitionsnecessarytosupportthezonesdefinedb

  5. objective-c - 在设置 Cocoa Pods 和安装 Ruby 更新时出错 - 2

    我正在尝试为我的iOS应用程序设置cocoapods但是当我执行命令时:sudogemupdate--system我收到错误消息:当前已安装最新版本。中止。当我进入cocoapods的下一步时:sudogeminstallcocoapods我在MacOS10.8.5上遇到错误:ERROR:Errorinstallingcocoapods:cocoapods-trunkrequiresRubyversion>=2.0.0.我在MacOS10.9.4上尝试了同样的操作,但出现错误:ERROR:Couldnotfindavalidgem'cocoapods'(>=0),hereiswhy:U

  6. ruby - 你会如何在 Ruby 中表达成语 "with this object, if it exists, do this"? - 2

    在Ruby(尤其是Rails)中,您经常需要检查某物是否存在,然后对其执行操作,例如:if@objects.any?puts"Wehavetheseobjects:"@objects.each{|o|puts"hello:#{o}"end这是最短的,一切都很好,但是如果你有@objects.some_association.something.hit_database.process而不是@objects呢?我将不得不在if表达式中重复两次,如果我不知道实现细节并且方法调用很昂贵怎么办?显而易见的选择是创建一个变量,然后测试它,然后处理它,但是你必须想出一个变量名(呃),它也会在内存中

  7. Ruby 的数字方法性能 - 2

    我正在使用Ruby解决一些ProjectEuler问题,特别是这里我要讨论的问题25(Fibonacci数列中包含1000位数字的第一项的索引是多少?)。起初,我使用的是Ruby2.2.3,我将问题编码为:number=3a=1b=2whileb.to_s.length但后来我发现2.4.2版本有一个名为digits的方法,这正是我需要的。我转换为代码:whileb.digits.length当我比较这两种方法时,digits慢得多。时间./025/problem025.rb0.13s用户0.02s系统80%cpu0.190总计./025/problem025.rb2.19s用户0.0

  8. ruby - Ruby 性能中的计时器 - 2

    我正在寻找一个用ruby​​演示计时器的在线示例,并发现了下面的代码。它按预期工作,但这个简单的程序使用30Mo内存(如Windows任务管理器中所示)和太多CPU有意义吗?非常感谢deftime_blockstart_time=Time.nowThread.new{yield}Time.now-start_timeenddefrepeat_every(seconds)whiletruedotime_spent=time_block{yield}#Tohandle-vesleepinteravalsleep(seconds-time_spent)iftime_spent

  9. ruby - 在 Ruby 中,为什么 Array.new(size, object) 创建一个由对同一对象的多个引用组成的数组? - 2

    如thisanswer中所述,Array.new(size,object)创建一个数组,其中size引用相同的object。hash=Hash.newa=Array.new(2,hash)a[0]['cat']='feline'a#=>[{"cat"=>"feline"},{"cat"=>"feline"}]a[1]['cat']='Felix'a#=>[{"cat"=>"Felix"},{"cat"=>"Felix"}]为什么Ruby会这样做,而不是对object进行dup或clone? 最佳答案 因为那是thedocumenta

  10. ruby-on-rails - 如果条件与 &&,是否有任何性能提升 - 2

    如果用户是所有者,我有一个条件来检查说删除和文章。delete_articleifuser.owner?另一种方式是user.owner?&&delete_article选择它有什么好处还是它只是一种写作风格 最佳答案 性能不太可能成为该声明的问题。第一个要好得多-它更容易阅读。您future的自己和其他将开始编写代码的人会为此感谢您。 关于ruby-on-rails-如果条件与&&,是否有任何性能提升,我们在StackOverflow上找到一个类似的问题:

随机推荐