Simon Kemper
Simon Kemper

Reputation: 645

Is accessing objects frequently using Computed Properties affecting performance?

I am writing a game using GameplayKit & SpriteKit Frameworks. In Apples examples about the GameplayKit you often see the following:

class PlayerEntity: GKEntity {
    // MARK: Components

    var renderComponent: RPRenderComponent {
        guard let renderComponent = componentForClass(RPRenderComponent.self) else {
            fatalError()
        }
        return renderComponent
    }
    var stateMachineComponent: RPStateMachineComponent {
        guard let stateMachineComponent = componentForClass(RPStateMachineComponent.self) else {
            fatalError()
        }
        return stateMachineComponent
    }
    // MARK: Initialisation
    override init() {
        super.init()

        let renderComponent = RPRenderComponent()
        renderComponent.node.entity = self;
        let stateMachineComponent = RPStateMachineComponent(states: [
            RPPlayerStandingState(entity: self),
            RPPlayerFallingState(entity: self),
            RPPlayerBouncingDownState(entity: self),
            RPPlayerBouncingUpState(entity: self),
            RPPlayerJumpingState(entity: self),
            RPPlayerBoostState(entity: self)
            ])
        addComponent(renderComponent)
        addComponent(stateMachineComponent)
    }
}

Components are created and initialized during the initialization of the class they belong to and added to the components-array via addComponent(component: GKComponent).

To make these components accessible from outside the class Apples example always use computed properties which call componentForClass() to return the corresponding component-instance.

The render component however is accessed 'per-frame' meaning that during every update-cycle I need to call the render component and this will lead to call the computed property which in my eyes leads to additional and avoidable processing-load.

Calling would look like:

func update(withDeltaTime time: NSTimeInterval) {
    playerEntity.renderNode.DoSomethingPerFrame()
}

Instead of this I am doing it like following:

class PlayerEntity: GKEntity {
    // MARK: Components

    let renderComponent: RPRenderComponent
    var stateMachineComponent: RPStateMachineComponent!

    // MARK: Initialisation
    override init() {
        renderComponent = RPRenderComponent()
        super.init()
        renderComponent.node.entity = self

        stateMachineComponent = RPStateMachineComponent(states: [
            RPPlayerStandingState(entity: self),
            RPPlayerFallingState(entity: self),
            RPPlayerBouncingDownState(entity: self),
            RPPlayerBouncingUpState(entity: self),
            RPPlayerJumpingState(entity: self),
            RPPlayerBoostState(entity: self)
            ])
        addComponent(renderComponent)
        addComponent(stateMachineComponent)

    }
}

Instead of getting access to the components using a computed property I am holding a strong reference to it in my class. In my eyes I am avoiding additional overhead when calling a computed property since I avoid that "computation".

But I am not pretty sure why Apple has done that using computed properties. Maybe I am totally wrong about computed properties or maybe it's just because this is the coding-style of the one who wrote that example!?

Are Computed Properties affecting performance? Do they automatically mean more overhead?

Or:

Is it OK and 'Safe' (in terms of resources) to use computed properties like this? (In my eyes computed properties are despite being afraid quite an elegant solution, btw.)

Upvotes: 1

Views: 83

Answers (1)

gnasher729
gnasher729

Reputation: 52632

It depends - how much each calculation of the property costs, and how often you do that calculation.

In general, you should use computed properties if the calculation cost is so low that it makes little difference, and functions if it takes longer. Alternatively, a computed property can cache its values if the computed property often returns the same result.

Used properly, there is very little cost involved. You also would need to suggest an alternative to a computed property that is as easy to use and faster.

Upvotes: 0

Related Questions