在 Swift 中使用 NSRectFill 推送像素时的性能问题

Posted

技术标签:

【中文标题】在 Swift 中使用 NSRectFill 推送像素时的性能问题【英文标题】:Performance problems while pushing pixels with NSRectFill in Swift 【发布时间】:2015-01-02 01:39:50 【问题描述】:

这是一个展示 Lorenz Attractor 图像的 Swift Playground。我有三个问题。如果只有第一个问题得到回答,我会考虑回答这个问题。

    一开始并没有那么快,但经过大约 8000-9000 次迭代后,它变得非常慢。任何想法为什么? 为什么 drawRect 被调用了两次? 有没有推荐的方法来获得不错的像素推送性能?
// Change platform to OS X when opening Playground.
// alt + cmd + enter to show Assistant editor and see resulting image.

import Cocoa
import XCPlayground

let width = 600.0, height = 500.0

class CustomView: NSView 
    override init(frame: NSRect) 
        super.init(frame: frame)
    

    required init?(coder: NSCoder) 
        super.init(coder: coder);
    

    override func drawRect(dirtyRect: NSRect) 
        lorentzAttractor()
    

    func lorentzAttractor() 
        var x = 0.1 , y = 0.0, z = 0.0, t = 0.0
        for i in 1...4242 
            let x1 = x + 0.01 * 10 * (y - x)
            let y1 = y + 0.01 * (x * (28 - z) - y)
            let z1 = z + 0.01 * (x * y - 2.66 * z)
            x = x1
            y = y1
            z = z1

            let phys_x = width / 2 + 12 * x
            let phys_y = 25 + 8 * z

            NSRectFill(NSMakeRect(CGFloat(phys_x), CGFloat(phys_y), 1, 1))
        
    


XCPShowView("Lorenz Attractor", CustomView(frame:
    NSRect(x: 0, y: 0, width: width, height: height)))

【问题讨论】:

你在开玩笑吗?我陷入了 2500 次迭代,不得不强制退出 Xcode! :) 虽然@matt 的回答可能最终满足您的所有需求,但一般来说,对单个像素执行“填充矩形”操作并不是您执行高性能图形绘制的方式——您可以考虑获取NSGraphicsContext 并直接在其中绘制。如果您有兴趣调查类似的事情,这个答案 (***.com/a/24139701/73297) 可能会提供一些有用的提示。 @BenZotto 这是很好的建议,但我什至没有看代码或算法——所以,事实上,我最终可能根本不会回答 OP 的问题。我只是指出,在操场上工作甚至与表现无关。我将该 OP 的代码粘贴到操场上,运行速度越来越慢,持续了 10 秒,最后停了下来。这与 0.013 秒内的 badda-bing badda-boom 有点不同。 :) 游乐场有疯狂的额外开销;他们根本不适合这种事情。 【参考方案1】:

问题是游乐场很烂。这是一个技术编程术语,所以我来领奖!

说真的,我将您的代码作为一个实际的应用程序运行,并在调用 lorentzAttractor() 之前和之后记录时间,得到了这个:

1420165414.02522
1420165414.03103

所以整个过程以百分之一秒的速度运行。不可怕。 (编辑:我后来做了一些后续测试,在更受控的条件下,我们在发布时没有这样做,并且获得了稍微好一点的时间,始终保持在 0.013 秒左右。)

回到我真正的观点:不要将游乐场用于任何事情。他们是魔鬼的杰作。当然不是为了测试任何东西的性能。游乐场与现实没有任何联系。

【讨论】:

我照你说的做了,现在我马上画了this。谢谢! 尽管它既不快也不习惯,但我还是在 GitHub 上发布了它。 github.com/jonelf/Lorenz-Attractor

以上是关于在 Swift 中使用 NSRectFill 推送像素时的性能问题的主要内容,如果未能解决你的问题,请参考以下文章

当用户使用 iOS 13 Swift 5 点击推送通知时,在特定视图中打开应用程序

Swift 2 Parse 推送通知

谷歌登录后使用 Swift 4 推送视图控制器

如何从fireBase推送通知swift 4中获取数据

当用户在 swift 中单击推送通知时打开自定义 url

当应用程序使用 Swift 在前台运行时显示推送通知