diff --git a/DotRecast.sln b/DotRecast.sln index 8130233..5a437de 100644 --- a/DotRecast.sln +++ b/DotRecast.sln @@ -39,6 +39,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotRecast.Detour.Extras.Tes EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotRecast.Detour.TileCache.Test", "test\DotRecast.Detour.TileCache.Test\DotRecast.Detour.TileCache.Test.csproj", "{3CAA7306-088E-4373-A406-99755CC2B605}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotRecast.Benchmark", "test\DotRecast.Benchmark\DotRecast.Benchmark.csproj", "{D1EFC625-D095-4208-98A2-112B73CB40B0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -112,6 +114,10 @@ Global {10395C8F-DFBD-4263-8A20-EA3500A6E55A}.Debug|Any CPU.Build.0 = Debug|Any CPU {10395C8F-DFBD-4263-8A20-EA3500A6E55A}.Release|Any CPU.ActiveCfg = Release|Any CPU {10395C8F-DFBD-4263-8A20-EA3500A6E55A}.Release|Any CPU.Build.0 = Release|Any CPU + {D1EFC625-D095-4208-98A2-112B73CB40B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D1EFC625-D095-4208-98A2-112B73CB40B0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D1EFC625-D095-4208-98A2-112B73CB40B0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D1EFC625-D095-4208-98A2-112B73CB40B0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {FFE40BBF-843B-41FA-8504-F4ABD166762E} = {8ED75CF7-A3D6-423D-8499-9316DD413DAD} @@ -130,5 +136,6 @@ Global {023E1E6A-4895-4573-89AE-3D5D8E0B39C8} = {8ED75CF7-A3D6-423D-8499-9316DD413DAD} {DF987948-8C23-4337-AF83-D87D6407518D} = {8ED75CF7-A3D6-423D-8499-9316DD413DAD} {10395C8F-DFBD-4263-8A20-EA3500A6E55A} = {A7CB8D8B-70DA-4567-8316-0659FCAE1C73} + {D1EFC625-D095-4208-98A2-112B73CB40B0} = {A7CB8D8B-70DA-4567-8316-0659FCAE1C73} EndGlobalSection EndGlobal diff --git a/test/DotRecast.Benchmark/Bench_Math_RcVec3f.cs b/test/DotRecast.Benchmark/Bench_Math_RcVec3f.cs new file mode 100644 index 0000000..179b2cc --- /dev/null +++ b/test/DotRecast.Benchmark/Bench_Math_RcVec3f.cs @@ -0,0 +1,67 @@ +using System.Numerics; +using System.Runtime.Intrinsics; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Engines; +using DotRecast.Core.Numerics; + +namespace CSharpBencchmark +{ + /* + */ + public class Bench_Math_RcVec3f + { + Consumer _consumer = new(); + + [Benchmark] + public void Dot_Vector3() + { + var v1 = new Vector3(1, 2, 3); + var v2 = new Vector3(1, 2, 3); + var v = Vector3.Dot(v1, v2); + _consumer.Consume(v); + } + + [Benchmark] + public void Dot_RcVec3f() + { + var v1 = new RcVec3f(1, 2, 3); + var v2 = new RcVec3f(1, 2, 3); + var v = RcVec3f.Dot(v1, v2); + _consumer.Consume(v); + } + + [Benchmark] + public void Cross_Vector3() + { + var v1 = new Vector3(1, 2, 3); + var v2 = new Vector3(1, 2, 3); + var v = Vector3.Cross(v1, v2); + _consumer.Consume(v); + } + + [Benchmark] + public void Cross_RcVec3f() + { + var v1 = new RcVec3f(1, 2, 3); + var v2 = new RcVec3f(1, 2, 3); + var v = RcVec3f.Cross(v1, v2); + _consumer.Consume(v); + } + + [Benchmark] + public void Normalize_Vector3() + { + var v1 = new Vector3(1, 2, 3); + var v = Vector3.Normalize(v1); + _consumer.Consume(v); + } + + [Benchmark] + public void Normalize_RcVec3f() + { + var v1 = new RcVec3f(1, 2, 3); + var v = RcVec3f.Normalize(v1); + _consumer.Consume(v); + } + } +} diff --git a/test/DotRecast.Benchmark/Bench_PriorityQueue.cs b/test/DotRecast.Benchmark/Bench_PriorityQueue.cs new file mode 100644 index 0000000..0dd9546 --- /dev/null +++ b/test/DotRecast.Benchmark/Bench_PriorityQueue.cs @@ -0,0 +1,164 @@ +using BenchmarkDotNet.Attributes; +using DotRecast.Core.Collections; + +namespace CSharpBencchmark +{ + /* + +| Method | Count | Mean | Error | StdDev | +|---------------- |------ |--------------:|-------------:|-------------:| +| Enqueue_rcQueue | 10 | 84.19 ns | 1.328 ns | 1.242 ns | +| Enqueue_heap | 10 | 208.44 ns | 3.522 ns | 5.981 ns | +| Enqueue_pqueue | 10 | 202.59 ns | 2.320 ns | 2.170 ns | +| Enqueue_rcQueue | 100 | 791.99 ns | 15.733 ns | 43.333 ns | +| Enqueue_heap | 100 | 3,136.11 ns | 57.433 ns | 50.912 ns | +| Enqueue_pqueue | 100 | 2,256.86 ns | 19.259 ns | 17.073 ns | +| Enqueue_rcQueue | 1000 | 7,258.35 ns | 55.554 ns | 49.247 ns | +| Enqueue_heap | 1000 | 31,613.03 ns | 602.311 ns | 591.550 ns | +| Enqueue_pqueue | 1000 | 24,313.61 ns | 463.713 ns | 455.429 ns | +| Enqueue_rcQueue | 10000 | 98,246.69 ns | 1,824.495 ns | 1,706.634 ns | +| Enqueue_heap | 10000 | 356,910.42 ns | 3,376.793 ns | 2,993.439 ns | +| Enqueue_pqueue | 10000 | 278,814.15 ns | 3,733.262 ns | 3,309.439 ns | + + */ + + public class Bench_PriorityQueue + { + [Params(10, 100, 1000, 10000)] + public int Count; + + RcSortedQueue _rcQueue; + //TBinaryHeap _heap; + PriorityQueue _pqueue; + + float[] _priority; + + class Node + { + public int id; + public float total; + } + + [GlobalSetup] + public void Setup() + { + Comparison _comparison = (x, y) => + { + var v = x.total.CompareTo(y.total); + if (v != 0) + return v; + return x.id.CompareTo(y.id); + }; + + _rcQueue = new(Count, _comparison); + //_heap = new(Count, _comparison); + _pqueue = new(Count, Comparer.Create(_comparison)); + + _priority = new float[Count]; + for (int i = 0; i < Count; i++) + { + _priority[i] = (float)Random.Shared.NextDouble() * 100f; + } + + Console.WriteLine("111"); + } + + [Benchmark] + public void Enqueue_rcQueue() + { + _rcQueue.Clear(); + for (int i = 0; i < Count; i++) + { + _rcQueue.Enqueue(new Node + { + id = i, + total = _priority[i], + }); + } + } + + //[Benchmark] + //public void Enqueue_heap() + //{ + // _heap.Clear(); + // for (int i = 0; i < Count; i++) + // { + // _heap.Push(new Node + // { + // id = i, + // total = _priority[i], + // }); + // } + //} + + [Benchmark] + public void Enqueue_pqueue() + { + _pqueue.Clear(); + for (int i = 0; i < Count; i++) + { + var node = new Node + { + id = i, + total = _priority[i], + }; + _pqueue.Enqueue(node, node); + } + } + + [Benchmark] + public void EnqueueDequeue_rcQueue() + { + for (int i = 0; i < Count; i++) + { + _rcQueue.Enqueue(new Node + { + id = i, + total = _priority[i], + }); + } + + while (_rcQueue.Count() > 0) + { + _rcQueue.Dequeue(); + } + } + + //[Benchmark] + //public void EnqueueDequeue_heap() + //{ + // for (int i = 0; i < Count; i++) + // { + // _heap.Push(new Node + // { + // id = i, + // total = _priority[i], + // }); + // } + + // while (_heap.Count > 0) + // { + // _heap.Pop(); + // } + //} + + [Benchmark] + public void EnqueueDequeue_pqueue() + { + for (int i = 0; i < Count; i++) + { + var node = new Node + { + id = i, + total = _priority[i], + }; + _pqueue.Enqueue(node, node); + } + + while (_pqueue.Count > 0) + { + _pqueue.Dequeue(); + } + } + } +} diff --git a/test/DotRecast.Benchmark/DotRecast.Benchmark.csproj b/test/DotRecast.Benchmark/DotRecast.Benchmark.csproj new file mode 100644 index 0000000..0a1d580 --- /dev/null +++ b/test/DotRecast.Benchmark/DotRecast.Benchmark.csproj @@ -0,0 +1,18 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + + + + diff --git a/test/DotRecast.Benchmark/Program.cs b/test/DotRecast.Benchmark/Program.cs new file mode 100644 index 0000000..2ca5fc5 --- /dev/null +++ b/test/DotRecast.Benchmark/Program.cs @@ -0,0 +1,7 @@ +using BenchmarkDotNet.Running; +using CSharpBencchmark; + +BenchmarkRunner.Run([ + //BenchmarkConverter.TypeToBenchmarks(typeof(Bench_PriorityQueue)), + BenchmarkConverter.TypeToBenchmarks(typeof(Bench_Math_RcVec3f)), +]);