Skip to content

Instantly share code, notes, and snippets.

@5argon
Last active June 18, 2020 03:21
Show Gist options
  • Save 5argon/849144dd3e766f415c08526dbfa0dcf6 to your computer and use it in GitHub Desktop.
Save 5argon/849144dd3e766f415c08526dbfa0dcf6 to your computer and use it in GitHub Desktop.
struct Work : IComponentData
{
public int id; //<-- use to determine whether to mark or tag.
public int value; //<-- work on this.
//public Junks junks;
}
struct Mark : IComponentData
{
public bool marked;
}
struct TagMark : IComponentData
{
}
struct Junks : IComponentData
{
public Junk junk1;
public Junk junk2;
public Junk junk3;
public Junk junk4;
public Junk junk5;
public Junk junk6;
public Junk junk7;
public Junk junk8;
}
struct Junk
{
public int4 i1;
public int4 i2;
public int4 i3;
public int4 i4;
public int4 i5;
public int4 i6;
public int4 i7;
public int4 i8;
}
[DisableAutoCreation]
class JustTag : JobComponentSystem
{
public int affectedEntities;
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
int affected = this.affectedEntities;
var ecb = new EntityCommandBuffer(Allocator.Temp);
Entities.ForEach((Entity e, in Work w) =>
{
if (w.id < affected)
{
ecb.AddComponent<TagMark>(e);
}
}).Run();
ecb.Playback(EntityManager);
ecb.Dispose();
return default;
}
}
[DisableAutoCreation]
class WorkOnTag : JobComponentSystem
{
public int affectedEntities;
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
Entities.WithAll<TagMark>().ForEach((ref Work w) => { w.value += 100; }).Run();
return default;
}
}
[DisableAutoCreation]
class JustMark : JobComponentSystem
{
public int affectedEntities;
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
int affected = this.affectedEntities;
Entities.ForEach((ref Mark m, in Work w) => { m.marked = w.id < affected; }).Run();
return default;
}
}
[DisableAutoCreation]
class WorkOnMark : JobComponentSystem
{
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
Entities.ForEach((ref Work w, in Mark m) => { w.value += m.marked ? 100 : 0; }).Run();
return default;
}
}
[Test, Performance]
public void TagVsNot([Values(10 , 100, 1000, 10000, 100000)] int entityCount,
[Values(0.2, 0.4, 0.6, 0.8, 1)] double affected)
{
int affectedEntities = (int) (entityCount * affected);
var world = new World("Test World");
var s1 = world.AddSystem(new JustMark());
var s2 = world.AddSystem(new WorkOnMark());
var s3 = world.AddSystem(new JustTag());
var s4 = world.AddSystem(new WorkOnTag());
s1.affectedEntities = affectedEntities;
s3.affectedEntities = affectedEntities;
var em = world.EntityManager;
//Setup entities each with unique ID.
var arc = em.CreateArchetype(
ComponentType.ReadOnly<Work>(),
ComponentType.ReadOnly<Mark>()
//ComponentType.ReadOnly<Junks>()
);
em.CreateEntity(arc, entityCount, Allocator.Temp).Dispose();
var cda = new NativeArray<Work>(entityCount, Allocator.TempJob);
for (int i = 0; i < entityCount; i++)
{
cda[i] = new Work {id = i};
}
var eq = em.CreateEntityQuery(ComponentType.ReadOnly<Work>());
var tagEq = em.CreateEntityQuery(ComponentType.ReadOnly<Tag>());
eq.CopyFromComponentDataArray(cda);
//Work based on if its ID is lower than a certain number or not.
Measure.Method(() =>
{
s1.Update();
s2.Update();
})
.Definition("Mark then work", SampleUnit.Microsecond)
.WarmupCount(5)
.MeasurementCount(190)
.Run();
Measure.Method(() =>
{
s3.Update();
s4.Update();
})
.Definition("Tag then work", SampleUnit.Microsecond)
.SetUp( () => em.RemoveComponent<Tag>(tagEq))
.WarmupCount(5)
.MeasurementCount(190)
.Run();
Measure.Method(() => s2.Update()).Definition("Just work on mark", SampleUnit.Microsecond)
.WarmupCount(5)
.MeasurementCount(190)
.Run();
Measure.Method(() => s4.Update()).Definition("Just work on tag", SampleUnit.Microsecond)
.WarmupCount(5)
.MeasurementCount(190)
.Run();
//Sanity check if they were really worked on.
using (var check = eq.ToComponentDataArray<Work>(Allocator.TempJob))
{
Assert.That(check.Length, Is.EqualTo(entityCount));
int workedCount = 0;
for (int i = 0; i < check.Length; i++)
{
if (check[i].value == (195 * 4) * 100) workedCount++;
}
Assert.That(workedCount, Is.EqualTo(affectedEntities));
}
cda.Dispose();
world.Dispose();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment