Alright so I'm working on a new iteration of Cornucopia and I'd like to improve the performance of my main cycle. I can chop it off in several different phases to speed it up a bit, but it's still slow and I'd like to know if there is anything I can do to improve it.
Basically, I need this:
- A list of all existing CollectibleEntity
- A list of all existing animals
- A list of all existing ore rocks
- A list of all existing loot containers (barrels, rad town crates, trash piles, etc.)
The code I use is this:
Each of these calls takes about 140 milliseconds on my server, so it amounts to almost 600 milliseconds which causes a hickup on the server when it happens.Code:var collectibles = Resources.FindObjectsOfTypeAll<CollectibleEntity>().Where(c => c.isActiveAndEnabled).ToList(); var animals= Resources.FindObjectsOfTypeAll<BaseNPC>().Where(c => c.isActiveAndEnabled).Cast<BaseEntity>(); var ores= Resources.FindObjectsOfTypeAll<BaseResource>().Where(c => c.isActiveAndEnabled).Cast<BaseEntity>(); var loots= Resources.FindObjectsOfTypeAll<LootContainer>().Where(c => c.isActiveAndEnabled).Cast<BaseEntity>();
I can easily chop it off to have only two of the calls per timer tick by separating animals, ores and loots into different cycles... but the collectibles, I need them for each cycle.
Is there a faster way to do this?
Performance issue: getting existing objects
Discussion in 'Rust Development' started by Deicide666ra, Aug 22, 2015.
-
Can't really help but i do recall the FindObject* methods are extremely slow because they sift through the entire server object list.
Thought about using OnEntitySpawned instead and maintain your own database of objects as they get created? -
Meh, I guess I could do that. Would really like a more performant way of getting it live instead of relying on a parallel structure.
-
just an idea, instead of calling for each FindObjectsOfTypeAll do it only once:
Code:var entities = Resources.FindObjectsOfTypeAll<BaseEntity>().Where(c => c.isActiveAndEnabled).ToArray(); var collectibles = entities.Where(c => c is CollectibleEntity).Cast<CollectibleEntity>().ToList(); var animals = entities.Where(c => c is BaseNPC); var ores = entities.Where(c => c is BaseResource); var loots = entities.Where(c => c is LootContainer);
-
Tried that Nogrod, the first call takes like 8.5 seconds.... Not exactly an improvement hehe.
I guess hooking OnEntitySpawned and OnEntityDeath or whatever the names of those hooks will probably be the best way. I mean it's not terrible as it is, but you do feel a little lag with the spawn cycle hits and I'd like to prevent that. -
on entitydeath doesn't exist i believe but you can add to your directory during onentityspawned and you can always delete items from it when you notice they point to a null reference now?
-
Doc says otherwise: http://docs.oxidemod.org/rust/#onentitydeath
Also the way C# works, checking for NULL in this case would not work as the reference will always remain valid so long as something references it. The actual entity might be deleted, but the reference to the instance will still be valid so long as it's not removed from any list or variable that references it. I suppose there are fields in there I could check to see if it's been "killed" or not... -
Right, my bad.
