I’m building for mobile a pretty simple game I converted from MonoBehaviour.
Rough stats are 60 entities (not all gui) across 25 chunks, 80 components, 70 systems and 40 jobs (not all running constantly). My heaviest entity has about 25 components.
Nearly all entities are unique so there’s no contiguous mem or burst benefits in such a game.
It all updates in SimulationGroup (0.02 timestep) and the bottleneck from the start has been the code loop which averages around 9ms with burst. I’ve been gradually optimising over weeks but am still struggling to get stable 60fps.
So I decided to run some basic tests to see what’s the starting point for ecs for normal games and it’s pretty dire, lest I’ve got something wrong. I don’t know if it’s just too much code overhead in the ecs mechanics or whether it’s thread related waits.
Test
I created 50 components, ComponentSystems and JobSystems. There are 50 entities each with 1 of the components so every system processes a single entity using either IJobForEach or Entities.ForEach(Comp) and just inc’s a couple of variables. (code at bottom)
Test phone is Galaxy s4.
50 JobComponentSystems ~6ms
50 Burst jobs = 1.5ms
5 instances of GatherChunks = 0.85ms
52 instances of GatherChunksAndOffsetsJob = ~1ms
14 ECB.PlayBack = 0.275ms
50 ComponentSystems ~8ms
212 instances of GatherChunks = ~3ms
64 ECB.PlayBack = ~1ms
50 GameObjects ~0.3ms
50 MonoBehaviour.Update() = 0.275ms
For the most part, individual jobs/functions only take about 0.03ms each (I think that’s min res of the timer) so that’s not the problem, It’s all the overhead surrounding them. The user code is doing virtually nothing (100 value increments) so all those milliseconds are pure overhead.
On PC and for large games, these overheads would be dwarfed by the positives of dots as megacity showed but for normal games on mobile, this is a problem.
If Job/ComponentSystems.OnUpdate() are to be the functions that replace MonoBehaviour.Update(), I wonder if Unity is keeping an eye on this overhead and whether its something that’s optimisable above where it currently is?
My game is still very early stages and only going to get more complex but there’s nothing I can do to get stable 60fps with ecs itself eating up 6-8ms every frame.
[UpdateInGroup(typeof(SimulationSystemGroup))]
public class JobSystem0 : JobComponentSystem
{
[BurstCompile]struct Job : IJobForEach<Comp0>
{
public void Execute(ref Comp0 c0)
{
c0.value++;
c0.value2++;
}
}
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
return new Job().Schedule(this, inputDeps);
}
}
[UpdateInGroup(typeof(SimulationSystemGroup))]
public class ComponentSystem0 : ComponentSystem
{
protected override void OnUpdate()
{
Entities.ForEach( (ref Comp0 c0) =>
{
c0.value++;
c0.value2++;
});
}
}
public struct Comp0 : IComponentData {public int value; public float value2;}
public struct Comp1 : IComponentData {public int value; public float value2;}
...
public struct Comp50 : IComponentData {public int value; public float value2;}
These systems are duplicated for each component but they don’t both run at the same time. I strip out either all ComponentSystems or all JobComponentSystems for tests.





