Skip to content

Commit

Permalink
2x speed up for delegates
Browse files Browse the repository at this point in the history
  • Loading branch information
andreakarasho committed Mar 10, 2024
1 parent fcd982f commit 1830d39
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 35 deletions.
2 changes: 1 addition & 1 deletion src/Archetype.cs
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ internal int FindMatch(ReadOnlySpan<Term> searching)
ref readonly var current = ref currents[i];
ref readonly var search = ref searching[j];

if (_comparer.Compare(current.ID, search.ID) == 0)
if (current.ID.CompareTo(search.ID) == 0)
{
if (search.Op != TermOp.With)
return -1;
Expand Down
156 changes: 122 additions & 34 deletions tools/TinyEcs.Generator/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,49 +107,39 @@ public partial {className}{filter}
sb.AppendLine($@"
public void Query<{typeParams}>({delegateName}<{typeParams}> fn) {whereParams}
{{
var hash = Lookup.Query<{(i > 0 ? "(" : "")}{typeParams}{(i > 0 ? ")" : "")}{filterMethod}>.Hash;
var terms = Lookup.Query<{(i > 0 ? "(" : "")}{typeParams}{(i > 0 ? ")" : "")}{filterMethod}>.Terms.AsSpan();
var withouts = Lookup.Query<{(i > 0 ? "(" : "")}{typeParams}{(i > 0 ? ")" : "")}{filterMethod}>.Withouts;
var arch = {(withFilter ? "_world." : "")}FindArchetype(hash, terms);
if (arch == null) return;
InternalQuery(arch, fn, terms, withouts);
static void InternalQuery
(
Archetype arch,
{delegateName}<{typeParams}> fn,
ReadOnlySpan<Term> terms,
IDictionary<ulong, Term> withouts
)
var query = new QueryInternal({(withFilter ? "_world." : "")}Archetypes, terms);
foreach (var arch in query)
{{
if (arch.Count > 0)
{columnIndices}
foreach (ref readonly var chunk in arch)
{{
{columnIndices}
{fieldList}
ref var last = ref Unsafe.Add(ref t0A, chunk.Count - 4);
ref var last2 = ref Unsafe.Add(ref t0A, chunk.Count);
foreach (ref readonly var chunk in arch)
while (Unsafe.IsAddressLessThan(ref t0A, ref last))
{{
{fieldList}
ref var last = ref Unsafe.Add(ref t0A, chunk.Count);
while (Unsafe.IsAddressLessThan(ref t0A, ref last))
{{
fn({signCallback});
{advanceField}
}}
}}
}}
fn({signCallback});
{advanceField}
var span = CollectionsMarshal.AsSpan(arch._edgesRight);
fn({signCallback});
{advanceField}
ref var start = ref MemoryMarshal.GetReference(span);
ref var end = ref Unsafe.Add(ref start, span.Length);
fn({signCallback});
{advanceField}
while (Unsafe.IsAddressLessThan(ref start, ref end))
{{
if (!withouts.ContainsKey(start.ComponentID))
InternalQuery(start.Archetype, fn, terms, withouts);
fn({signCallback});
{advanceField}
}}
start = ref Unsafe.Add(ref start, 1);
while (Unsafe.IsAddressLessThan(ref t0A, ref last2))
{{
fn({signCallback});
{advanceField}
}}
}}
}}
}}
Expand All @@ -161,6 +151,104 @@ IDictionary<ulong, Term> withouts
return sb.ToString();
}

// static string GenerateFilterQuery(bool withFilter, bool withEntityView)
// {
// var className = withFilter ? "struct FilterQuery" : "class World";
// var filter = withFilter ? "<TFilter>" : "";
// var filterMethod = withFilter ? ", TFilter" : "";
// var delegateName = withEntityView ? "QueryFilterDelegateWithEntity" : "QueryFilterDelegate";

// var sb = new StringBuilder();
// sb.AppendLine($@"
// public partial {className}{filter}
// {{
// ");

// for (var i = 0; i < MAX_GENERICS; ++i)
// {
// var typeParams = GenerateSequence(i + 1, ", ", j => $"T{j}");
// var whereParams = GenerateSequence(i + 1, " ",j => $"where T{j} : struct");
// var columnIndices = GenerateSequence(i + 1, "\n" , j => $"var column{j} = arch.GetComponentIndex<T{j}>();");
// var fieldList = (withEntityView ? "ref var entityA = ref chunk.Entities[0];\n" : "") +
// GenerateSequence(i + 1, "\n" , j => $"ref var t{j}A = ref chunk.GetReference<T{j}>(column{j});");
// var signCallback = (withEntityView ? "entityA, " : "") +
// GenerateSequence(i + 1, ", " , j => $"ref t{j}A");
// var advanceField = (withEntityView ? "entityA = ref Unsafe.Add(ref entityA, 1);\n" : "") +
// GenerateSequence(i + 1, "\n" , j => $"t{j}A = ref Unsafe.Add(ref t{j}A, 1);");

// sb.AppendLine($@"
// public void Query<{typeParams}>({delegateName}<{typeParams}> fn) {whereParams}
// {{
// var hash = Lookup.Query<{(i > 0 ? "(" : "")}{typeParams}{(i > 0 ? ")" : "")}{filterMethod}>.Hash;
// var terms = Lookup.Query<{(i > 0 ? "(" : "")}{typeParams}{(i > 0 ? ")" : "")}{filterMethod}>.Terms.AsSpan();
// var withouts = Lookup.Query<{(i > 0 ? "(" : "")}{typeParams}{(i > 0 ? ")" : "")}{filterMethod}>.Withouts;
// var arch = {(withFilter ? "_world." : "")}FindArchetype(hash, terms);
// if (arch == null) return;
// InternalQuery(arch, fn, terms, withouts);

// static void InternalQuery
// (
// Archetype arch,
// {delegateName}<{typeParams}> fn,
// ReadOnlySpan<Term> terms,
// IDictionary<ulong, Term> withouts
// )
// {{
// if (arch.Count > 0)
// {{
// {columnIndices}

// foreach (ref readonly var chunk in arch)
// {{
// {fieldList}
// ref var last = ref Unsafe.Add(ref t0A, chunk.Count - 4);
// ref var last2 = ref Unsafe.Add(ref t0A, chunk.Count);

// while (Unsafe.IsAddressLessThan(ref t0A, ref last))
// {{
// fn({signCallback});
// {advanceField}

// fn({signCallback});
// {advanceField}

// fn({signCallback});
// {advanceField}

// fn({signCallback});
// {advanceField}
// }}

// while (Unsafe.IsAddressLessThan(ref t0A, ref last2))
// {{
// fn({signCallback});
// {advanceField}
// }}
// }}
// }}

// var span = CollectionsMarshal.AsSpan(arch._edgesRight);

// ref var start = ref MemoryMarshal.GetReference(span);
// ref var end = ref Unsafe.Add(ref start, span.Length);

// while (Unsafe.IsAddressLessThan(ref start, ref end))
// {{
// if (!withouts.ContainsKey(start.ComponentID))
// InternalQuery(start.Archetype, fn, terms, withouts);

// start = ref Unsafe.Add(ref start, 1);
// }}
// }}
// }}
// ");
// }

// sb.AppendLine("}");

// return sb.ToString();
// }

static string GenerateSequence(int count, string separator, Func<int, string> generator)
{
var sb = new StringBuilder();
Expand Down

0 comments on commit 1830d39

Please sign in to comment.