Tick-Based Casting Performance

Hello,

Here’s a more general question than my usual specific queries. Today I’m curious to ask about the specifics when it comes to Casting every tick. The reason why I’m asking is that I am making a couple of components that allow for a wide variety of Translation, Rotation, and Scaling actions. Since I aim to make this natively compatible with Actors and Components of different types, I am wondering if it is better for performance to save the targetted element as a UObject and then Cast every time the process runs (essentially every tick when active) to check which specific functions to use; or instead if I should have different Uproperties saved for all options and then depending on elements, just check which variables have a valid saved reference. I am asking furthermore since I know that the draw-cost on tick elements in C++ is significantly lower when running on native code instead of Blueprints.

it’s not “free” but that would be far far far from a perf question even if you did 10 000 cast per frame

no need to optimize on that side for a classic project (even AAA), you will have way more perf hit on many places where you can optimize

That depends on what do you use to cast, if you use UE4’s Cast function

Cast<ASomething>(Something);

That function checks if type of casting object is correct and nullptr if not, it takes few extra instructions to do so, but it should not be a big issue. One of benefits it it’s safe as oyu can do null check ot see if type is right

But because in C++ types are just virtual thing that exists only in compilation time, there so called “C-style cast” which cast type on compilation time:

(ASomething*)Something;

Compiler assumes programmer is 100% sure that this pointer will be of type cast to correct type and usually unconditionally accept change of type during compilation, it does not generate extra instructions as generate instruction will now simply read the variable as it is the new type. There a small problem, it assumes you are 100% sure what you are doing, if you cast to incompatible type this may end up memory corruption and messing up the object, so if you gonna use it you need to be 100% sure that casted type will memory align with new type.

There also exception to the rule, some primitive types (int, float) casting may require instructions to convert, it depends on target CPU architecture, C++ also allows for cast overloads (https://www.learncpp.com/cpp-tutorial/910-overloading-typecasts/) which obviously add instructions that you write to preform conversion.

C++ also introduce more cast methods (to C) which you can read here and most likely wont use it in UE4:

/doc/oldtutorial/typecasting/

But again using Cast function is not really a big performance issue or else you doing really crazy stuff, and there countless way to avoid casting (starting by simple keeping casted variable in to nee variable with new type) at all in tick

As always, superbly detailed answer. I am using UE4’s default casting

AActor* Actor = Cast<AActor>(Object);
USceneComponent* Component = Cast<USceneComponent>(Object);
if (!Actor && !Component) //For NonScene Components, save the Comp's Owner.
{
	UActorComponent* TempComp = Cast<UActorComponent>(Object);
	if (TempComp)
	{
	      Actor = TempComp->GetOwner();
	}
}

It seems like this casting is okay for the time being, I’ll further optimize instruction and branching distribution in the future; right now I’m simply trying to get it to work properly from a functionality pov.

Thanks!