Looping though children is insanely slow compared to manually tracking and picking by uid.. Why?

0 favourites
  • 7 posts
From the Asset Store
For Adventure, Action, Heroes, Sci-fi and Action-RPG games.
  • Edit: Bug report at github.com/Scirra/Construct-bugs/issues/8230

    Project file : drive.google.com/file/d/1Aq1BkpicNGKQhw9GnLaNRa-KhgsLy94Z/view

    In a test, Looping through and picking children in a scene graph is insanely slow compared to manually tracking and looping though array lists of uid attached to a parent and then picking those children objects by uid. Via constructs child picking I get 2 fps and 100% cpu. Via manual uid tracking and picking, I get 60fps without only 25% cpu.

    This doesn't seen right.

    I once happened upon a bug that caused a dictionary and array forloops to run extremely slow. But that bug increased the lag exponentially with every item added to the loop.

    Why is picking an object's children so slow compared to manually tracking and picking those same children from UID?

    For example, if I create 1000 parents and attach 10 children to each parent, and the loop through each parent, picking children, and then looping through the children, I get 2 frames a second.

    But, If I do the same, but instead add an array for each parent to store child UIDs and add 10 children to each array. Then when I loop through each parent, picking each parents array by uid, then loop through each element in the array, picking a child by uid, I get much better results.

    The uid method runs 120 faster than the scene graph method.

  • On further investigation, I tried to see if there was an exponential relationship between the number of children and the time it takes to iterate through them. I need to dig deeper, but it seems to be true.

    1 child runs runs at 30 fps, 2 children at 14fps, and so on. Whatever is happening internally to fetch children or mess with the sol is extremely slow.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • ... Wow that's extremely surprising, nice catch.

    Tested and got:

    72% CPU when holding space with Array method.

    100% CPU (2fps) when holding space with Hierarchy method.

    It's especially weird considering there's extra picking with the Array method, having to pick the Array for each parent, doesn't make logical sense at all as I thought picking extra object would always be a bad idea!

    My project is heavily using hierarchies and picking of children/parents, with loops just like this with "for each child". I'm often battling CPU usage even though I have mostly made my project "function-based" so not a lot of events running every tick (but still a few bits essential to run every tick), but once a handful of hierarchies appear onscreen with about 10 to 20 children per parent, does tend to spike CPU to 30% or so (which is acceptable but then when more gameplay stuff is occurring, reaching 70% and such)

    I really hope this is simply a bug, otherwise this is a temptation to refactor 8k events to move back to the UID method. Do love hierarchies though, but wow.

  • I love hierarchies too, this should definitely be reported. I hope Ashley will fix it in LTS version.

  • Yeah, I was starting to switch to the convenience of hierarchies when I noticed this. I very much prefer being able to build templates and attach children objects for additional functionality. It makes for much cleaner events than picking by uid.

    On picking though, it is very, VERY, fast. Picking an object by uid is blazing fast as far as I can tell, and negligible on performance unless it forces you to use a for loop you didn't need to use.

    It would be really cool if you could have children automatically associated in terms of picking. Like, if we could have another "self" type keyword that allows you to reference a child or parent in batch without a foreach loop/

    On a side note, if you use functions for nearly everything, and have performance pains, It is good to understand a raw function call can cost 8x the price as an empty event. That may be insubstantial if the processing for logic implemented is high, but sometimes, the event itself (empty) can have a higher cost than the ACES it calls. I had a project using a lot of vector rotations and such, and the most costly part of the math was the overhead of the events and function calls. I created a bunch of math functions through events. And it was bad, especially when you have function calls in function calls. I wrapped that functionality into a plugin and then just call the ACES I created. If I need to run rotations on a bunch of projectiles, for example, the savings was well worth it.

  • Ruskul Could you report it?

    Looks like "Pick children" condition is the culprit. Disabling "for each child" doesn't make much difference.

    Damn, this is awful.. I just checked - we have over 500 "Pick children" events in our project. This can explain some weird performance problems in the game.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)