Which one is faster in blueprint : Get all actors of class OR Get all actors with tag ?
I am working on a mobile game and this is very important
If there’s a lot of actors and speed is important, then don’t use either. Use event dispatchers.
If the number of actors in < 20, say, it doesn’t matter.
Researched this a long time ago here is the post:
https://www.casualdistractiongames.c…tallactorswith
tldr - Internally, on each class, UE4 maintains a hashmap of all instances of it.
afaik GetAllActorsFromClass should be orders of magnitude faster than GetAllActorsWithInterface and GetAllActorsWithTag, since it utilizes that class specific HashMap. (Deep class hierarchies still require traversing)
Disclaimer: I haven’t looked into this for a long while - so things may have changed. It’s worth digging in to the source if you are curious as there are several interesting things to discover…If you do, please be sure to post any additional findings…
Just to clarify - if you have 1000 actors in your level, and 5 of them are of Class FOO and also tagged FOO:
For GetAllActorsFromClass , TActorIterator should be traversing a HashMap of 5 where GetAllActorsWithTag is traversing the full 1000.
Just ran a quick test:
In a scene with 40000 actors in it:
GetAllActorsWithTag takes about .0039 seconds
GetAllActorsFromClass **.000011
BTW Looks like there is also a GetAllActorsOfClassWithTag node now too… sweet.**
What about the hard referencing? Say you have 1000 actors that need to be saved before the level unloads, and they all need to bind to a certain blueprint that calls the “onSaving” ED, for them to pass their data to the GI, for example.
All of them have to hard reference that one blueprint. Isn’t that blueprint being replicated in memory 1000 times at that point?
If the 1000 are all the same type of actor, it only gets loaded into memory once.
Not if you use a dispatcher, that’s the point I was making
How? You mean the same class? Is there any documentation on this?
Well, you have to have a hard reference to bind to, right?
If you have a level with 5000 of the same class in it, that class only gets loaded once for the level.
All this business with soft/hard references, is to stop the engine loading thing you aren’t going to use.
If you’ve got 5000 in the level, well, er, you are using it.
Yes… but all 1000 actors bind to ONE dispatcher.
Got it, they bind to one dispatcher, obviously. But each still needs to reference the caller, right? Like you said, 5000 times.
Yes, but that’s fairly trivial, it’s not going to be eating memory like, textures, for instance.
Any official documentation on this? How much memory exactly, what?
I assume there’s no docs, because if you’re really that bothered about how a dispatcher is setup, you can just look in the engine code ( no, I have not looked ).
But I can tell you, it’s a handful of bytes for each actor. So even if you have 1000s of binding actors, it’s still nowhere as bad as even ONE texture
Does Get All Actors With Tag create a hard reference in runtime? I assumed this because it has to search for all the actors with a tag and then load this into memory. Or am I mistaken?
It depends what you do with the actors you get back.
If you make an interface call on them, there’s no hard refs, but if you cast them, you have hard refs at runtime and in editor.
Thank you so much for getting back to me on this because I’ve been really confused about the whole thing. I was told that even things associated with Interfaces like: Get All Actors With Interface, or Get All Widgets With Interface, or With tag like I have in my example, would be exactly the same as using a Get All Actors Of Class because the memory load has to do with Unreal needing to search for all of those actors and then store them until they are used.
This is what I was concerned about because if you have like 90 actors in your game and then stored in an array, isn’t searching for all of those actors with an interface technically still loading all 90 whether you are using them or not? And then at what point are they being unloaded after use or not being used? I had trouble believing what I was told because I felt it would defeat the entire purpose of even using interfaces if they create hard refs just like casting does.
I’m really trying to understand at what point does this become taxing on the memory. Can you give me a more detailed explanation?
As you can see in my set-up here, I had the nodes placed to where after the message is sent to the actor with the tag, the array with the stored actors then clears to free up memory. Or at least I hoped that it would work that way. But is something like that even necessary? And is it even being used correctly?
I prefer to use get all actors or widgets with interface, but I want to be sure about it. It’s always so tricky because we cannot really see what is being loaded into memory during runtime.
If I’m not mistaken:
- Get All Actor of Class only iterates over a hash of all actors of the given class that are part of the world. Just like @OptimisticMonkey says above.
- Get All Actor With Interface iterates over every actor in the world and checks
if (Actor->GetClass()->ImplementsInterface(Interface))
. - Get All Actor With Tag is the same as with interface but checks
if (Actor->ActorHasTag(Tag))
.
I can’t find the post, but I remember some time ago @Chatouille tested and concluded the return array was treated as weak pointers, meaning they don’t keep any actor from getting GCed. Only one of the node was tested, though.
So if I’m not mistaken:
They are not the same. All are fairly expensive compared to Get All Actors Of Class.
Nothing is loaded with these nodes. What is returned is a copy of the memory address of the instances in the world.
They are treated a TWeakPtr<>
meaning it will not prevent destruction of the referenced objects. (I’ll update if I can find the post)
In the image the only memory you are freeing is the actor instance at index 0 when destroyed and the allocated space of the array,an array thats not really necesarry in this particular case. That would be the 64-bit size reference per index + some overhead for the array.
Hope this makes sense.
Anyone is more than welcome to correct or add anything.
You mentioned that the pointers are even more expensive than the Get All Actors Of Class so are they expensive in the sense that they are holding onto Data from the actors, or are they expensive because it takes a while to search for all actors in the world? My main goal is to avoid any hard references for optimal performance.
Because I use things like Get All Actors Or Widgets With Interfaces/Tags, I just want to know how using those nodes to retrieve actors and their data to send messages, is any different from a cast. Either way, you’re having to reference the actors in both situations beforehand, whether you are using interfaces or casting. And that data is loaded onto the actor that calls these functions to scan the world. If you’re using this over and over again, sending messages, it would seem as though these actors would have to be permanently loaded into memory. It cannot be garbage collected as long as you’re still using it, and it still exists within the Level.
So why is it that one is not considered a hard reference when the other is? That step of getting all actors with something has to take place in either situation in order for anything to work. Nothing will show up in references in the editor, but I imagine that is not the case in runtime, since this is when the node searching for the interfaces is actually called.