syncHierarchy performance issue

Hi all,

I am working on a performance intensive project - I do regular profiling with Chrome Devtools and I see a lot of time is spent on syncHierarchy (and _sync) with plenty of entities in the scene.

I have been looking at the source and I do understand what is going on but I have a nagging feeling this is taking way too much time than it should. For example with around 300 entities (most of them not even in view) syncHierarchy calls take up almost half of the render time.

Obviously having less children per entity could/should save some time - but that is not always feasible.

Are there any other ways to speed up or skip this call?
For example could I (easily) replace it with another similar function?
I our case syncing could be skipped as well when an entity is not visible (or not visibleThisFrame).

Am I missing something? This is our first project in PlayCanvas - coming from Unity - and not everything is similarly explainable.

Thanks!
-Pieter

AFAIK, syncHierarchy calls _sync if the entity has moved in the world somehow (eg, being rotated every frame) and that cost scales if you have more entities.

Maybe @will has some ideas about this?

Yeah - would love to hear other ideas or thoughts behind it.

I forgot to mention we’re pushing quite some skinned characters so there are more graphnodes to process then just the visual entity.

I now ‘modded’ my own version of the function so I have a bit more control of what could/should be synced.

Nevertheless any other ideas or thoughts are more than welcome!

Thanks!
-Pieter

It doesn’t matter if something is not in view. The hierarchy must be checked because an entity may have moved since last frame and now actually be on screen.

It’s unusual for syncHierarchy to take half as much time as rendering. Are you able to share a link to a scene that exhibits this behavior?

BTW, a cool think about the PlayCanvas engine is that it’s open source. If you have ideas about how to improve the current implementation, feel free to open an issue or better yet, submit a PR.

Hi @will! Thanks for your reply!

I understand that for most user cases syncing the hierarchy must be done - even when it is out of view.
There are however scenarios where you would manually want to decide if it should be done or not - especially when doing your own culling.

Nevertheless, I spent a bit more time looking into it. I have a test with 300 skinned characters - on my machine this takes around 5ms to do all the syncHierarchy calls (regardless if they are in/out of view).

I have monkeypatched both graphnode and the syncHierarchy function to check for an additional _shouldSync var. If it is false it returns instantly. I only set the skinned characters to _shouldSync = false. With 300 characters it drops down to around 0.8ms and the characters still update. I suspect a similar syncHierarchy call is made/done when updating the skeleton (as the animation still plays normally).

It is a pretty big performance gain - although I am not sure if this will bite me later on in production.
I am running out of time for deeper investigation - and for now my solution ‘works’.

It is a private project - you’re welcome to take a look. I will send you a link later on.

Pieter

Ah, ok, so when you said ‘300 entities’, that’s not quite the full story. Because each skinned character has a number of bones (not a lot by the looks of things - maybe 10 per character or so). So really, it’s around 3000 nodes being synced, an order of magnitude higher.

Your approach sounds OK - I don’t think it should have any nasty side effects.

We probably could benefit from adding better control for this kind of thing. Maybe start a GitHub issue to kick off a discussion?

Thanks for the reply!

I did forget it in my first post - corrected it in my second one (although probably not very clear though - sorry)
So far I am not running into any issues - so pretty happy with the workaround. Will start a GitHub issue.

Thanks,
Pieter