Hi, so I was curious about the performance impact using Playmaker vs regular script which led me to do a couple of tests. While not exact, for me, they can still be a general guide to when planning the design of the FSMs.
The test was made in an empty scene and in profiler targeted to a build. They're an estimate of the lowest and highest ms of the Update.ScriptRunBehaviourUpdate.
The scene has 200 game objects with 2 FSMs each (400FSM in total).Cost of Playmaker FSM itself:How much is the overhead cost of just having a running FSM?
- The FSM states are doing nothing. Script is a new script (empty Start() and Update())
- No FSM enabled 0.01 - 0.06ms
- 400 FSMs Enaled 0.18 - 0.68ms
- No FSMs, 400 scripts enabled 0.02 - 0.07ms
Conclusion: PlaymakerFSM has an overhead cost, scripts doesn't
Turning FSM on and offSo if there is a cost to just having FSMs running, it should be more effective turning them off when not used?
- One of the two FSMs(200 in total) is enabling and disabling the other FSM
- FSM turning on and off every frame: 0.75 - 2.82ms
- Same as above, 1 sec interval: 0.21 - 2.75ms
Conclusion: There is a cost the moment FSM is enabled and disabled, while turning 400 on and off at the same time is extreme case, might not be a good idea to do with a lot of FSMs used very frequently.
LoopsHow about the loops?
Both FSMs have a state with "int add" action. One scenario with "every frame" checked, the other scenario with a "next frame event" action that loop back to the same event.
- Every frame ticked: 0.24 - 1.64ms
- Next frame event: 0.57 - 4.16ms
Conclusion: This was a bit surprising as the result feels significant. So at the moment, it feels using "every frame" is more performant than using the next frame to create a loop(usually when using action sequence).
Broadcast AllHow about using broadcast all?
- One FSM that broadcast all event to the 400 FSMs, or a script doing the same.
- Broadcast from FSM: 0.09 - 0.28ms
- Broadcast from script: 0.07 - 0.32ms
Conclusion: "broadcast all" is the same from a script and an FSM.
Final Thoughts:While the tests aren't exact, I think they show a relative cost between the scenarios put against each other.
- I've had projects where I had FSMs to environment objects such as trees. Objects that you usually have a couple of hundreds in the scene.
So my conclusion would lead me to believe, even though the FSMs are doing nothing there is still a big cost to have them running. My previous solution was to disable the FSMs, colliders, and visuals when the object goes out of the camera. So this would be a balance between the cost of having them all running and the cost of constantly turning them on and off. Best would of course to have a manager FSM that did everything for the objects when needed. Or activate them when needed through collision etc.
- The result would also indicate that I should use "every frame" as much as possible, especially with FSMs in a constant loop.
- I would use scripts as much as possible, especially for small things that just have a small responsibility (is I would be comfortable writing this in a script) to decrease the number of FSMs running.
I would love to get more insight into this, maybe there are other things as garbage collection(which I don't understand much about) that I'm missing.