Is there a significant perf difference in this?

LocalVector = (_cachedFooBarZoo + SomeCalculatedThing(inputs));
LocalVector = (_someOtherComponent.Data.FooBarZoo + SomeCalculatedThing(inputs));

The difference is reaching into a known GameObject / Component for data versus caching it. I want to cache things but would prefer the live connection to the data if there’s no significant impact.

Depends, if it is called only ones, then no. If it is called multiple times, then caching it is better for performance.

It depends on what ‘Data’ and ‘FooBarZoo’ is. Primarily if they’re getter properties, or direct field accessors.

If they’re property getters, technically speaking, that’ll be a function call to access both ‘Data’ and ‘FooBarZoo’. Where as if they’re fields, it’s a direct access to the value where it stands.

Of course though, the difference is NOT significant at all. To notice it, you’d have to do it millions of times in a row.

Caching is more useful if it’s a ‘GetComponent’ call. Or some other call that is a complex function.

getter/setter properties shouldn’t really ever be complex calls (although unity breaks this rule with the various component properties on every component that hide a ‘GetComponent’ call… this is why it was removed in Unity 5).

2 Likes

Caching makes sense when the operation is time expensive. There is a cost though:

  1. You are duplicating the data, so this is memory expensive (though not likely a lot more expensive)
  2. You are “denormalizing”; if the original changes, you have to worry about stale data

Personally, I would do:

LocalVector = (GetFooBarZoo() + SomeCalculatedThing(inputs));

which would be slower than both of your samples. However, it would then be easy to change

FooBarZoo GetFooBarZoo()
{
  return _someOtherComponent.Data.FooBarZoo;
}

to

FooBarZoo _cachedFooBarZoo
FooBarZoo GetFooBarZoo()
{
  if (_cachedFooBarZoo == default(FooBarZoo))
    _cachedFooBarZoo = _someOtherComponent.Data.FooBarZoo;
  return _cachedFooBarZoo;
}

if I ever found out accessing that property was really slow.

1 Like

Interesting, that answers my question. In this specific case there shouldn’t be basically no difference doing it one way or the other in terms of performance.

It was just something I wonder about when I’m presented with the choice, so thanks for clarifying for me.

Performance has been covered well already. I agree, structure and maintainability are more important.

With that in mind sometimes it makes sense not to allow classes to ‘pull through’ others.

So this

foo.bar.zoo;

Can be replaced with this

foo.zoo;

// inside Foo
public Zoo zoo {
    get {
        return bar.zoo;
    }
}

On the face of it this is more complex. But it allows you to change the implementation of Foo and Bar without affecting any of the methods that call Foo.zoo

The advice in this post was of a general nature and may not apply to your specific situation. Please consult the documentation and consider if this advice is right for you.

1 Like