Skip to content

Jobify Add Component

What

Adding component is often sequential and unoptimised. This code pattern has a AddComponent inside a loop:

// in System.OnUpdate
var ecb = new EntityCommandBuffer(Allocator.Temp);
foreach ((Comp1 c1, Comp2 c2, Entity entity) in SystemAPI.Query<Comp1, Comp2>().WithEntityAccess()) {
    ecb.AddComponent(entity, new Comp3{
        Value = func1(c1.Value, c2.Value)
    });
}
ecb.Playback(EntityManager);
ecb.Dispose();

Why

This can be optimised by using Query-based API and jobifying.

How

[BurstCompile]
internal partial struct SetCompJob : IJobEntity {
    public void Execute(in Comp1 c1, in Comp2 c2, ref Comp3 c3) {
        c3.Value = func1(c1.Value, c2.Value);
    }
}

[BurstCompile]
internal partial struct AddCompSystem : ISystem {
    public void OnUpdate(ref SystemState state) {
        state.EntityManager.AddComponent<Comp3>(SystemAPI.QueryBuilder().WithAll<Comp1, Comp2>().Build());
        new SetCompJob().ScheduleParallel();
    }
}
The Query-based API AddComponent make a structural change per chunk, which is faster than one structural change per entity. SetCompJob execute func1 in parallel which is also faster than being sequential.