Skip to content

Commit

Permalink
Add descendants variation test, 2.1.2
Browse files Browse the repository at this point in the history
  • Loading branch information
neuecc committed Aug 9, 2016
1 parent cf6142a commit d6f0b48
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 6 deletions.
32 changes: 32 additions & 0 deletions Assets/Editor/Tests/TraverseTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,5 +131,37 @@ public void AfterSelf()
Origin.Child("Sphere_B").AfterSelfAndSelf().Where(x => x.name == "Sphere_B").Select(x => x.name)
.IsCollection("Sphere_B", "Sphere_B");
}

[Test]
public void DescendantsVariation()
{
{
Origin.Descendants().ToArray().Select(x => x.name)
.IsCollection("Sphere_A", "Sphere_B", "Group", "P1", "Group", "Sphere_B", "P2", "Sphere_A", "Sphere_B");

Origin.Descendants().ToArray(x => x.name)
.IsCollection("Sphere_A", "Sphere_B", "Group", "P1", "Group", "Sphere_B", "P2", "Sphere_A", "Sphere_B");

Origin.Descendants().ToArray(x => x.name == "Sphere_B").Select(x => x.name).IsCollection("Sphere_B", "Sphere_B", "Sphere_B");

Origin.Descendants().ToArray(x => x.name == "Sphere_B", x => x.name).IsCollection("Sphere_B", "Sphere_B", "Sphere_B");

Origin.Descendants().ToArray(x => x.name, x => x == "Sphere_B", x => x).IsCollection("Sphere_B", "Sphere_B", "Sphere_B");


var l = new List<string>();
Origin.Descendants().ForEach(x => l.Add(x.name));
l.IsCollection("Sphere_A", "Sphere_B", "Group", "P1", "Group", "Sphere_B", "P2", "Sphere_A", "Sphere_B");
}
{
Origin.Descendants().OfComponent<Transform>().ToArray().Select(x => x.name)
.IsCollection("Sphere_A", "Sphere_B", "Group", "P1", "Group", "Sphere_B", "P2", "Sphere_A", "Sphere_B");


var l = new List<string>();
Origin.Descendants().OfComponent<Transform>().ForEach(x => l.Add(x.name));
l.IsCollection("Sphere_A", "Sphere_B", "Group", "P1", "Group", "Sphere_B", "P2", "Sphere_A", "Sphere_B");
}
}
}
}
6 changes: 5 additions & 1 deletion Assets/LINQtoGameObject/README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,11 @@ void Update()

`ToArray` and `ToArrayNonAlloc` have five overloads. `()`, `(Func<GameObject, T> selector)`, `(Func<GameObject, bool> filter)`, `(Func<GameObject, bool> filter, Func<GameObject, T> selector)`, `(Func<GameObject, TState> let, Func<TState, bool> filter, Func<TState, T> selector)` for Optimize `Where().Select().ToArray()` pattern.

If you use simple iteration or `ToArrayNonAlloc`, LINQ to GameObject guarantees no gc allocate and performance is very fast. If you use `DescendantsAndSelf().OfComponent<T>()`, it may possible to substitude `GetComponentsInChildren<T>` that is always fast than LINQ traverse(because LINQ traverse can not have native magics). So you can substitude native methods, use it. If you needs other query, use LINQ.
If you use simple iteration or use `ForEach` or `ToArrayNonAlloc`, LINQ to GameObject guarantees no gc allocate and performance is very fast.

If you use `DescendantsAndSelf().OfComponent<T>()`, it may possible to substitude `GetComponentsInChildren<T>` that is always fast than LINQ traverse(because LINQ traverse can not have native magics). So you can substitude native methods, use it. If you needs other query, use LINQ.

> Descendants(AndSelf) returns single Component on each GameObject, GetComponentsInChildren returns multiple GameObject, behaviour is different. LINQ to GameObject's Descendants is heavily optimized, internal iterator of `ForEach` and `ToArray` is specialize tuned.

Author Info
---
Expand Down
34 changes: 30 additions & 4 deletions Assets/Sandbox/Perf.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,41 @@ void Start()
var sw = System.Diagnostics.Stopwatch.StartNew();
Profiler.BeginSample("Perf:LINQ");
var e = root.DescendantsAndSelf().OfComponent<Text>().GetEnumerator();
var e = root.DescendantsAndSelf().GetEnumerator();
while (e.MoveNext())
{
count++;
// this.GetComponent(
//var _ = e.Current.GetComponent<Perf>();
//l1.Add(e.Current.name);
}
Profiler.EndSample();
sw.Stop();
Debug.Log("LINQ:" + count + ":" + sw.Elapsed.TotalMilliseconds + "ms");
}
{
var count = 0;
var sw = System.Diagnostics.Stopwatch.StartNew();
Profiler.BeginSample("Perf:LINQ2");
root.DescendantsAndSelf().ForEach(_ => { });
Profiler.EndSample();
sw.Stop();
Debug.Log("LINQ ForEach:" + count + ":" + sw.Elapsed.TotalMilliseconds + "ms");
}
{
var sw = System.Diagnostics.Stopwatch.StartNew();
Profiler.BeginSample("Perf:Native");
var e = root.GetComponentsInChildren<Text>(true);
var e = root.GetComponentsInChildren<Transform>(true);
Profiler.EndSample();
sw.Stop();
Expand Down Expand Up @@ -75,6 +90,17 @@ void Start()

legacy.onClick.AddListener(() =>
{
var count = 0;
var sw = System.Diagnostics.Stopwatch.StartNew();
Profiler.BeginSample("Perf:Legacy");
var e = LegacyDescendants(root, true).OfComponent<Text>().GetEnumerator();
while (e.MoveNext())
{
count++;
}
Profiler.EndSample();
sw.Stop();
});
}

Expand Down
Binary file modified Assets/Sandbox/Perf.unity
Binary file not shown.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,11 @@ void Update()

`ToArray` and `ToArrayNonAlloc` have five overloads. `()`, `(Func<GameObject, T> selector)`, `(Func<GameObject, bool> filter)`, `(Func<GameObject, bool> filter, Func<GameObject, T> selector)`, `(Func<GameObject, TState> let, Func<TState, bool> filter, Func<TState, T> selector)` for Optimize `Where().Select().ToArray()` pattern.

If you use simple iteration or `ToArrayNonAlloc`, LINQ to GameObject guarantees no gc allocate and performance is very fast. If you use `DescendantsAndSelf().OfComponent<T>()`, it may possible to substitude `GetComponentsInChildren<T>` that is always fast than LINQ traverse(because LINQ traverse can not have native magics). So you can substitude native methods, use it. If you needs other query, use LINQ.
If you use simple iteration or use `ForEach` or `ToArrayNonAlloc`, LINQ to GameObject guarantees no gc allocate and performance is very fast.

If you use `DescendantsAndSelf().OfComponent<T>()`, it may possible to substitude `GetComponentsInChildren<T>` that is always fast than LINQ traverse(because LINQ traverse can not have native magics). So you can substitude native methods, use it. If you needs other query, use LINQ.

> Descendants(AndSelf) returns single Component on each GameObject, GetComponentsInChildren returns multiple GameObject, behaviour is different. LINQ to GameObject's Descendants is heavily optimized, internal iterator of `ForEach` and `ToArray` is specialize tuned.
Author Info
---
Expand Down

0 comments on commit d6f0b48

Please sign in to comment.