Casting vs Class Equal To

Hi,

Just a quick question as I couldn’t find an definitive answer, is casting to an object:

https://forums.unrealengine.com/core/image/gif;base64

Effectively the same as these two nodes:

https://forums.unrealengine.com/core/image/gif;base64

Is there any real difference performance wise?

Thanks

I’m not sure if there’s something wrong with the images (they appear broken for me), but Cast is very fast and efficient, to the point you can almost think of it as not costing any resources.

I’m not sure what happened to the pictures either… But basically I’m talking about this node:

Vs

Casting…

Personally I would have thought they would effectively be the same in essence because surely under the hood that’s all UE is doing… Just curious as to which is the preferred method people tend to use and as to whether one is more efficient than the other.

Thanks

1 Like

“Casting” actually has a minor impact that may add up if you do it too much (inside Tick events of many actors, etc).
They could impact your code performance if abused, it’s worth watching this series if you didn’t already:

https://www.unrealengine.com/en-US/e…depth—part-1
https://www.unrealengine.com/en-US/e…depth—part-2

1 Like

I have a widget debugger that is so riddled with tick casts that it more than halves the performance. It was getting so criminal that I now have tick boxes allowing sections of the debugger to do its thing. It does add up incredibility quickly when abused.

Cast returns an object or tells you it’s the wrong object type when it fails. *Equal *just tells you T/F. Apples vs oranges scenario, but the oranges are black and white and binary. You can’t compare the two.

If I understand the engine code correctly, casting creates a reference and makes sure everything is loaded or loads it if it’s not. So that’s why it can spiral out of control if you nest them or call them repeatedly.

Pretty much what I was told (and experienced), yeah. This also becomes painfully obvious with widgets, where nodes hang on to the references and Garbage Collection does not pick them up. Can be forced, of course. It’s a tad better these days but still manifests every now and then.

Yes but from a point of view of working out which object you are interacting with, personally I would have thought Class Equal would be quicker.

Technically you don’t even need to cast after that as you know that’s the class you are talking to.

I understand what you are saying about comparing the two, I personally just dont see the point in casting when class equal exists unless I am missing something obvious…

If the goal is to only determine whether it’s a specific object type or not, then I’d agree with this. Can’t back it up with hard data but I’d say Equal check should be virtually cost-free compared to a cast.

1 Like

Of course you have to, in case you want to call a function or access a variable of the class you are casting to (except if you are using an interface). If you don’t need any specific data or call, then naturally there is no need to cast.

Actually the assets are pre-loaded, meaning that when the Blueprint asset is loaded, it checks which other assets it references to (and casts also add references), so it’s gonna increase the initial load time, casting itself does not load any new assets.

I’d be interested how can you force impure nodes to release the references for their cached output value (in case that’s what you are referring to).

That’s probably true for C++, maybe not so much in BP, as VM calls are kinda expensive, and while an impure Cast is 1 node, an equal check is at least 3.

You can manually call Collect Garbage (it is slow); it seems to work for return values providing there’s nothing else referencing the object. I’ve been having problems with widgets persisting despite clearing their references and removing them from their respective parents. This helped although I’m unsure what’s the scope of this method’s usefulness.

Not going to pretend I understand well enough how BP nodes parse (not even talking about nativization here). I do know they’re giant blocks of text and 3 is more than 1. So I’ll roll with that. Thanks for shedding some light on this.

Well, it would be great if it would be documented somewhere how long references in pins are hold. If for example you had a delay after an impure call, after which Delay you want to use the result of that node… can you be sure it’s not cleaned up yet? Or what are the exact rules for it? Sounds quite critical.

In some cases *indefinitely *prior to 4.17: “Assets that are only referenced by pins inside active Blueprints will now correctly be garbage collected. This means that if you use LoadAsset to load something and do not store it for future usage, it will no longer stay in memory forever until the loading Blueprint is destroyed.”

The GC was improved over the years and sped up but it was still an issue for widgets in 4.21. As of now, not sure, I’ve been manually keeping track of widgets and trashing them when numbers do not add up.

It will not be cleaned up. From my experience the result will be valid for as long as the calling object is valid *and *the return value actually points at something valid.

The problem arises when the opposite situation takes place, you attempt to destroy an object but the GC goes “ah, no, no - something is still referencing it” (the return value) so it’s going to be *pending kill *forever. I believe that *most *of those kinks have been ironed out, though.

Technically that’s not true in a blueprint, you can just get the actor ref you are talking about and take a pin straight to/from the function / variable.

You don’t have to cast at all in that case.

I really hope it will sort itself out and we don’t have to deal with it :smiley:

I don’t know what you mean, you can’t connect a non-Actor object to the pin of an Actor object (and it applies to every other class too, you can’t just connect a Widget to a function of a UserWidget without casting).

I think we are talking cross purposes here but you can most certainly take an actor object ref and directly access variables and functions without casting to it.

If you have the correct object type already (since we’re accessing its functions and vars) why the heck would you need to cast or check what class it is in the first place? That’s what we’re thinking. But…

This. Just to clarify, you do not care about accessing the object at all, right? You just want to test whether it is specific class or not. What is faster? A Success / Fail on cast vs Equal To.

These are faster :stuck_out_tongue:

1 Like

As I said cross purposes … I guess I meant for an object of an already know type (sorry should have clarified that bit). I should have stated that you don’t have to cast in general to an already known object type.

So getting back on topic, yeah lets just say that you just want to know a type of object, you might not want to do anything with it necessarily, just simply to know what type of object you are talking about. In a pure simple form it seems to me like Equal To is the faster option in that case. Obviously if you want to do something with that object afterwards you would still be casting to it, so in that case just casting would be more efficient.

It does seem from some of the responses though that Casting has it overheads, hence the question.

If the cast is most usually successful here, won’t it be even slower? I’m pretty sure the Cast node itself also checks for failures (so that the failure check is done 2 times), and you also have an extra VM call (which is also expensive), and then we didn’t even talk about the extra complexity it adds to the graph.

It might still be useful in situations, but as far as I can see, it’s a bit of an overkill.

Independently, generally speaking, if there are so many casts that it actually affects performance, then something is likely wrong and the system could be restructured to avoid it.