Skip to content

Instantly share code, notes, and snippets.

@5argon
Last active July 8, 2018 08:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 5argon/95de98f5fbb6c0e8f4d4cd8c8c2e6ba1 to your computer and use it in GitHub Desktop.
Save 5argon/95de98f5fbb6c0e8f4d4cd8c8c2e6ba1 to your computer and use it in GitHub Desktop.
Unity ECS filter speed SetFilter vs. ForEachFilter printed on the console as CSV (Result : https://gist.github.com/5argon/1bb412d218eb6872418fe2f867a20435)
using System.Collections.Generic;
using NUnit.Framework;
using System.Linq;
using Unity.Entities;
using Unity.Collections;
using System.Diagnostics;
public struct IntData : IComponentData { public int data; public override string ToString() => data.ToString(); }
public struct Category : ISharedComponentData { public int category; }
public class FilteringSpeed : TestBase
{
private class CS : ComponentSystem
{
struct InjectedGroup
{
public ComponentDataArray<IntData> datas;
[ReadOnly] public SharedComponentDataArray<Category> category;
public readonly int GroupIndex;
}
[Inject] InjectedGroup injectedGroup;
protected override void OnUpdate() { }
public void SetFilterTest(Stopwatch sw, int category)
{
UpdateInjectedComponentGroups();
var cg = ComponentGroups[injectedGroup.GroupIndex];
sw.Start();
for (int i = 0; i < category; i++)
{
cg.SetFilter(new Category { category = i });
var cda = cg.GetComponentDataArray<IntData>();
for (int ij = 0; ij < cda.Length; ij++)
{
var d = cda[ij];
d.data++;
cda[ij] = d;
}
}
sw.Stop();
}
public void ForEachFilterTest(Stopwatch sw, int category)
{
UpdateInjectedComponentGroups();
var cg = ComponentGroups[injectedGroup.GroupIndex];
sw.Start();
var l = new List<Category>();
for (int i = 0; i < category; i++)
{
l.Add(new Category { category = i });
}
using (var filter = cg.CreateForEachFilter(l))
{
for (int i = 0; i < category; i++)
{
var cda = cg.GetComponentDataArray<IntData>(filter,i);
for (int ij = 0; ij < cda.Length; ij++)
{
var d = cda[ij];
d.data++;
cda[ij] = d;
}
}
}
sw.Stop();
}
}
[Test]
public void RunTest([Values(10,100,1000)] int entitiesPerCategory, [Values(5,10,25,50,100,1000)] int kindsOfCategory, [Values(1,3,5,10,50,100)] int categoryToFilter)
{
if(categoryToFilter > kindsOfCategory)
{
UnityEngine.Debug.Log($"0,0,0,0,0");
Assert.Fail();
}
var w = new World("TestWorld");
var em = w.GetOrCreateManager<EntityManager>();
var cs = w.CreateManager<CS>();
var eet = em.BeginExclusiveEntityTransaction();
for (int j = 0; j < kindsOfCategory; j++)
{
for (int i = 0; i < entitiesPerCategory; i++)
{
var e = eet.CreateEntity(typeof(IntData), typeof(Category));
eet.SetComponentData(e, new IntData { data = i });
eet.SetSharedComponentData(e, new Category { category = j });
}
}
em.EndExclusiveEntityTransaction();
Stopwatch swSetFilter = new Stopwatch();
Stopwatch swForEachFilter = new Stopwatch();
List<long> setFilterResults = new List<long>();
List<long> forEachFilterResults = new List<long>();
for (int i = 0; i < 10; i++)
{
swSetFilter.Reset();
swForEachFilter.Reset();
cs.SetFilterTest(swSetFilter, categoryToFilter);
cs.ForEachFilterTest(swForEachFilter, categoryToFilter);
if(i != 0)
{
setFilterResults.Add(swSetFilter.ElapsedTicks);
forEachFilterResults.Add(swForEachFilter.ElapsedTicks);
}
}
UnityEngine.Debug.Log($"{entitiesPerCategory},{kindsOfCategory},{categoryToFilter},{setFilterResults.Average()},{forEachFilterResults.Average()}");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment