为什么快速功能如此昂贵?

时间:2017-03-27 07:59:01

标签: ios swift function sprite-kit

为什么快速功能如此昂贵?

我一直在使用SpriteKit编写应用程序。每一帧,我都会在update()函数中重新计算CameraNode的位置。让我们称之为//(cameraNodeCode)。目前的设置对每秒的帧数几乎没有影响,它保持在60。

override func update() {
    //(cameraNodeCode)
}

由于cameraNodeCode非常大,我认为最好简化我的代码并将其放入函数中:updateCameraNode()。现在这就是我所拥有的:

func updateCameraNode() {
    //(cameraNodeCode)
}

override func update() {
    updateCameraNode()
}

当我设置这样的代码时,每秒的帧数突然降到了20,我感到非常惊讶,因为我没想到功能这么昂贵。我决定用这段代码测试我的理论:

func emptyFunction() {

}

override func update() {
    emptyFunction()
    emptyFunction()
    emptyFunction()
    emptyFunction()
    emptyFunction()
}

正如我预测的那样,当我这样做时,每秒的帧数急剧下降,达到每秒4.1帧!

我的问题是:

  • 为什么会这样?这是我的想法,因为简单地调用一个函数是如此昂贵,或者是否有我遗漏的东西?
  • 有没有办法让我的代码看起来很简单而不需要每秒20帧?

更新

我遗漏的关键信息是我正在使用Xcode游乐场。我认为这是SpriteKit和游乐场的错误。我有一个与Apple有关的错误报告,所以我会看到它在哪里。

2 个答案:

答案 0 :(得分:3)

谈到Sprite-kit,我已经在一个全新的“Hello world”模板中测试了你的代码到我的iPhone 7:

import SpriteKit
class GameScene: SKScene {
    private var label : SKLabelNode?
    override func didMove(to view: SKView) {

        // Get label node from scene and store it for use later
        self.label = self.childNode(withName: "//helloLabel") as? SKLabelNode
        if let label = self.label {
            label.alpha = 0.0
            label.run(SKAction.fadeIn(withDuration: 2.0))
        }
    }
    func emptyFunction() {}
    override func update(_ currentTime: TimeInterval) {
        // Called before each frame is rendered
        //emptyFunction()
        //emptyFunction()
        //emptyFunction()
        //emptyFunction()
        //emptyFunction()
    }
}

如果我没有在update方法中注释掉行(删除//),则没有任何变化。我总是60fps。检查你的项目,找出导致fps大幅下降的行,或者如果你将代码测试到模拟器试试真实的设备。希望它有所帮助。

答案 1 :(得分:2)

Swift有三种不同的调度方法,具有不同的性能特征:

  • 直接调度应该非常快。也称为 Static Dispatch
  • 由于见证表中的方法查找,
  • 表调度有点慢。也称为动态调度
  • Method Dispatch 是最动态的调度方法。但是,它也是三者中最慢的一个。

您可以通过向方法添加final来强制编译器使用静态分派:

final func emptyFunction() {
}

这也将为编译器提供额外的优化机会,例如内联代码。请记住在启用优化的情况下构建,而调试版本则不然。因此,您应确保选择 release 配置进行性能测试。 Swift项目的调试版本通常很慢。

有关方法调度和static关键字的详细信息,请参阅this post on the Swift blog

This great post解释了Swift中的三种方法调度以及何时使用它们。