From c03650187939bd45a136eb84a8282fa72406338e Mon Sep 17 00:00:00 2001 From: Sarofc Date: Sun, 7 Jul 2024 19:05:35 +0800 Subject: [PATCH] opt UpdateMoveRequest UpdateTopologyOptimization # Conflicts: # src/DotRecast.Detour.Crowd/DtCrowd.cs Benchmark b3 b4 --- .../Collections/RcBinaryHeap.cs | 161 ++++++++++++ src/DotRecast.Recast.Demo/Program.cs | 1 - .../DotRecast.Benchmark/Bench_Math_RcVec3f.cs | 67 ----- .../Bench_PriorityQueue.cs | 164 ------------ test/DotRecast.Benchmark/BenchmarkProgram.cs | 18 ++ .../Benchmarks/PriorityQueueBenchmarks.cs | 241 ++++++++++++++++++ .../Benchmarks/StackallocBenchmarks.cs | 71 ++++++ .../Benchmarks/VectorBenchmarks.cs | 73 ++++++ .../DotRecast.Benchmark.csproj | 7 +- test/DotRecast.Benchmark/Program.cs | 7 - 10 files changed, 568 insertions(+), 242 deletions(-) create mode 100644 src/DotRecast.Core/Collections/RcBinaryHeap.cs delete mode 100644 test/DotRecast.Benchmark/Bench_Math_RcVec3f.cs delete mode 100644 test/DotRecast.Benchmark/Bench_PriorityQueue.cs create mode 100644 test/DotRecast.Benchmark/BenchmarkProgram.cs create mode 100644 test/DotRecast.Benchmark/Benchmarks/PriorityQueueBenchmarks.cs create mode 100644 test/DotRecast.Benchmark/Benchmarks/StackallocBenchmarks.cs create mode 100644 test/DotRecast.Benchmark/Benchmarks/VectorBenchmarks.cs delete mode 100644 test/DotRecast.Benchmark/Program.cs diff --git a/src/DotRecast.Core/Collections/RcBinaryHeap.cs b/src/DotRecast.Core/Collections/RcBinaryHeap.cs new file mode 100644 index 0000000..5d4ff12 --- /dev/null +++ b/src/DotRecast.Core/Collections/RcBinaryHeap.cs @@ -0,0 +1,161 @@ +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Text; + +namespace DotRecast.Core.Collections +{ + public sealed class RcBinaryHeap + { + public int Count => _count; + public int Capacity => _values.Length; + + public T this[int index] => _values[index]; + + private T[] _values; + private int _count; + + private Comparison _comparision; + + public RcBinaryHeap(Comparison comparison) : this(8, comparison) + { + } + + public RcBinaryHeap(int capacity, Comparison comparison) + { + if (capacity <= 0) + throw new ArgumentException("capacity must greater than zero"); + + _values = new T[capacity]; + _comparision = comparison; + _count = 0; + } + + public void Push(T val) + { + EnsureCapacity(); + + _values[_count++] = val; + + UpHeap(_count - 1); + } + + public T Pop() + { + if (_count == 0) + { + Throw(); + + static void Throw() => + throw new InvalidOperationException("no element to pop"); + } + + Swap(0, --_count); + DownHeap(1); + + return _values[_count]; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public T Top() + { + return _values[0]; + } + + public void Modify(T node) + { + for (int i = 0; i < _count; i++) + { + if (_values[i].Equals(node)) + { + UpHeap(i); + return; + } + } + } + + public void Clear() + { + Array.Clear(_values, 0, _count); + _count = 0; + } + + public void FastClear() + { + _count = 0; + } + + public T[] ToArray() + { + var copy = new T[_count]; + Array.Copy(_values, copy, _count); + return copy; + } + + public void ReBuild() + { + for (int i = _count / 2; i >= 1; i--) + { + DownHeap(i); + } + } + + private void EnsureCapacity() + { + if (_values.Length <= _count) + { + var newValues = new T[Capacity * 2]; + Array.Copy(_values, newValues, _count); + _values = newValues; + } + } + + private void UpHeap(int i) + { + int p = (i - 1) / 2; + while (p >= 0) + { + if (_comparision(_values[p], _values[i]) <= 0) + break; + + Swap(p, i); + + i = p; + p = (i - 1) / 2; + } + } + + private void DownHeap(int i) + { + T d = _values[i - 1]; + int child; + while (i <= _count / 2) + { + child = i * 2; + if (child < _count && _comparision(_values[child - 1], _values[child]) > 0) + child++; + + if (_comparision(d, _values[child - 1]) <= 0) + break; + + _values[i - 1] = _values[child - 1]; + i = child; + } + _values[i - 1] = d; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void Swap(int x, int y) + { + if (x == y) + return; + (_values[y], _values[x]) = (_values[x], _values[y]); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsEmpty() + { + return _count == 0; + } + } +} diff --git a/src/DotRecast.Recast.Demo/Program.cs b/src/DotRecast.Recast.Demo/Program.cs index c0af359..6789bf2 100644 --- a/src/DotRecast.Recast.Demo/Program.cs +++ b/src/DotRecast.Recast.Demo/Program.cs @@ -3,7 +3,6 @@ using System.Threading; using DotRecast.Core; using DotRecast.Recast.Demo.Logging.Sinks; using Serilog; -using Serilog.Enrichers; namespace DotRecast.Recast.Demo; diff --git a/test/DotRecast.Benchmark/Bench_Math_RcVec3f.cs b/test/DotRecast.Benchmark/Bench_Math_RcVec3f.cs deleted file mode 100644 index 179b2cc..0000000 --- a/test/DotRecast.Benchmark/Bench_Math_RcVec3f.cs +++ /dev/null @@ -1,67 +0,0 @@ -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 deleted file mode 100644 index 0dd9546..0000000 --- a/test/DotRecast.Benchmark/Bench_PriorityQueue.cs +++ /dev/null @@ -1,164 +0,0 @@ -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/BenchmarkProgram.cs b/test/DotRecast.Benchmark/BenchmarkProgram.cs new file mode 100644 index 0000000..47b3601 --- /dev/null +++ b/test/DotRecast.Benchmark/BenchmarkProgram.cs @@ -0,0 +1,18 @@ +using BenchmarkDotNet.Running; +using DotRecast.Benchmark.Benchmarks; + +namespace DotRecast.Benchmark; + +public static class BenchmarkProgram +{ + public static int Main(string[] args) + { + var summary = BenchmarkRunner.Run([ + //BenchmarkConverter.TypeToBenchmarks(typeof(VectorBenchmarks)), + //BenchmarkConverter.TypeToBenchmarks(typeof(PriorityQueueBenchmarks)), + BenchmarkConverter.TypeToBenchmarks(typeof(StackallocBenchmarks)), + ]); + + return 0; + } +} \ No newline at end of file diff --git a/test/DotRecast.Benchmark/Benchmarks/PriorityQueueBenchmarks.cs b/test/DotRecast.Benchmark/Benchmarks/PriorityQueueBenchmarks.cs new file mode 100644 index 0000000..f44b8bd --- /dev/null +++ b/test/DotRecast.Benchmark/Benchmarks/PriorityQueueBenchmarks.cs @@ -0,0 +1,241 @@ +using System; +using System.Collections.Generic; +using BenchmarkDotNet.Attributes; +using DotRecast.Core.Collections; + +namespace DotRecast.Benchmark.Benchmarks; + +/* + +| Method | Count | Mean | Error | StdDev | Median | +| ---------------------- | --------- | ---------------: | ---------------: | ---------------: | ---------------: | +| **Enqueue_rcQueue** | **10** | **83.81 ns** | **1.722 ns** | **2.925 ns** | **83.00 ns** | +| Enqueue_heap | 10 | 173.27 ns | 3.431 ns | 3.813 ns | 172.40 ns | +| Enqueue_pqueue | 10 | 151.13 ns | 3.045 ns | 3.625 ns | 151.81 ns | +| DequeueAll_rcQueue | 10 | 293.28 ns | 5.368 ns | 5.021 ns | 293.56 ns | +| DequeueAll_heap | 10 | 409.89 ns | 4.982 ns | 4.416 ns | 410.04 ns | +| DequeueAll_pqueue | 10 | 448.56 ns | 4.490 ns | 3.980 ns | 448.17 ns | +| EnqueueDequeue_rcQueue | 10 | 116.73 ns | 0.126 ns | 0.105 ns | 116.72 ns | +| EnqueueDequeue_heap | 10 | 130.94 ns | 0.936 ns | 0.781 ns | 130.80 ns | +| EnqueueDequeue_pqueue | 10 | 101.39 ns | 0.589 ns | 0.551 ns | 101.14 ns | +| **Enqueue_rcQueue** | **100** | **690.10 ns** | **1.463 ns** | **1.297 ns** | **689.74 ns** | +| Enqueue_heap | 100 | 2,517.08 ns | 8.466 ns | 7.070 ns | 2,515.99 ns | +| Enqueue_pqueue | 100 | 2,188.55 ns | 26.386 ns | 24.682 ns | 2,193.53 ns | +| DequeueAll_rcQueue | 100 | 4,862.85 ns | 71.216 ns | 59.469 ns | 4,849.71 ns | +| DequeueAll_heap | 100 | 8,791.09 ns | 145.019 ns | 183.403 ns | 8,731.62 ns | +| DequeueAll_pqueue | 100 | 10,819.65 ns | 97.138 ns | 90.863 ns | 10,837.05 ns | +| EnqueueDequeue_rcQueue | 100 | 1,123.50 ns | 10.281 ns | 9.114 ns | 1,119.03 ns | +| EnqueueDequeue_heap | 100 | 1,228.70 ns | 4.664 ns | 3.894 ns | 1,227.22 ns | +| EnqueueDequeue_pqueue | 100 | 968.43 ns | 19.095 ns | 30.834 ns | 963.56 ns | +| **Enqueue_rcQueue** | **1000** | **7,416.73 ns** | **147.213 ns** | **229.193 ns** | **7,377.16 ns** | +| Enqueue_heap | 1000 | 35,362.30 ns | 478.398 ns | 447.494 ns | 35,391.69 ns | +| Enqueue_pqueue | 1000 | 24,861.28 ns | 438.919 ns | 389.091 ns | 24,737.34 ns | +| DequeueAll_rcQueue | 1000 | 81,520.39 ns | 299.823 ns | 250.366 ns | 81,538.01 ns | +| DequeueAll_heap | 1000 | 150,237.95 ns | 475.349 ns | 371.121 ns | 150,241.44 ns | +| DequeueAll_pqueue | 1000 | 166,375.18 ns | 1,105.089 ns | 1,033.701 ns | 166,338.45 ns | +| EnqueueDequeue_rcQueue | 1000 | 10,984.87 ns | 44.043 ns | 41.198 ns | 10,985.13 ns | +| EnqueueDequeue_heap | 1000 | 14,047.62 ns | 174.581 ns | 163.303 ns | 14,061.52 ns | +| EnqueueDequeue_pqueue | 1000 | 9,105.53 ns | 90.691 ns | 80.395 ns | 9,102.35 ns | +| **Enqueue_rcQueue** | **10000** | **90,623.51 ns** | **1,526.788 ns** | **1,353.458 ns** | **90,429.58 ns** | +| Enqueue_heap | 10000 | 347,060.71 ns | 4,511.258 ns | 3,767.105 ns | 347,319.53 ns | +| Enqueue_pqueue | 10000 | 287,118.46 ns | 3,091.524 ns | 2,581.562 ns | 286,254.88 ns | +| DequeueAll_rcQueue | 10000 | 1,245,536.36 ns | 7,701.471 ns | 6,827.153 ns | 1,245,206.25 ns | +| DequeueAll_heap | 10000 | 1,935,679.51 ns | 2,327.083 ns | 1,816.833 ns | 1,935,649.51 ns | +| DequeueAll_pqueue | 10000 | 2,541,652.37 ns | 7,807.705 ns | 7,303.332 ns | 2,543,812.50 ns | +| EnqueueDequeue_rcQueue | 10000 | 121,456.00 ns | 2,210.749 ns | 5,079.562 ns | 119,552.48 ns | +| EnqueueDequeue_heap | 10000 | 144,426.41 ns | 2,700.978 ns | 2,526.496 ns | 143,537.16 ns | +| EnqueueDequeue_pqueue | 10000 | 102,263.93 ns | 984.973 ns | 873.153 ns | 102,031.01 ns | + +*/ + +public class PriorityQueueBenchmarks +{ + [Params(10, 100, 1000, 10000)] public int Count; + + private RcSortedQueue _rcQueue; + private RcBinaryHeap _heap; + private PriorityQueue _pqueue; + + private float[] _priority; + + class Node + { + public int id; + public float total; + } + + [GlobalSetup] + public void Setup() + { + static int Comp(Node x, Node y) + { + var v = x.total.CompareTo(y.total); + if (v != 0) + return v; + return x.id.CompareTo(y.id); + } + + _rcQueue = new(Comp); + _heap = new(Count, Comp); + _pqueue = new(Count, Comparer.Create(Comp)); + + _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 DequeueAll_rcQueue() + { + _rcQueue.Clear(); + 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 DequeueAll_heap() + { + _heap.Clear(); + 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 DequeueAll_pqueue() + { + _pqueue.Clear(); + 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(); + } + } + + + [Benchmark] + public void EnqueueDequeue_rcQueue() + { + _rcQueue.Clear(); + for (int i = 0; i < Count; i++) + { + _rcQueue.Enqueue(new Node + { + id = i, + total = _priority[i], + }); + + _rcQueue.Dequeue(); + } + } + + [Benchmark] + public void EnqueueDequeue_heap() + { + _heap.Clear(); + for (int i = 0; i < Count; i++) + { + _heap.Push(new Node + { + id = i, + total = _priority[i], + }); + + _heap.Pop(); + } + } + + [Benchmark] + public void EnqueueDequeue_pqueue() + { + _pqueue.Clear(); + for (int i = 0; i < Count; i++) + { + var node = new Node + { + id = i, + total = _priority[i], + }; + _pqueue.Enqueue(node, node); + + _pqueue.Dequeue(); + } + } +} \ No newline at end of file diff --git a/test/DotRecast.Benchmark/Benchmarks/StackallocBenchmarks.cs b/test/DotRecast.Benchmark/Benchmarks/StackallocBenchmarks.cs new file mode 100644 index 0000000..bc542e4 --- /dev/null +++ b/test/DotRecast.Benchmark/Benchmarks/StackallocBenchmarks.cs @@ -0,0 +1,71 @@ +using System; +using System.Runtime.CompilerServices; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Engines; + +namespace DotRecast.Benchmark.Benchmarks; + +/* + +| Method | TestArraySize | Mean | Error | StdDev | Median | +|------------------------------- |-------------- |-------------:|-----------:|------------:|-------------:| +| Stackalloc_Long | 16 | 3.016 ns | 0.0179 ns | 0.0149 ns | 3.017 ns | +| Stackalloc_Long_SkipLocalsInit | 16 | 2.265 ns | 0.0197 ns | 0.0184 ns | 2.258 ns | +| New_Long | 16 | 5.917 ns | 0.1964 ns | 0.5634 ns | 5.761 ns | +| New_Long_SkipLocalsInit | 16 | 5.703 ns | 0.1371 ns | 0.3935 ns | 5.661 ns | +| Stackalloc_Long | 256 | 39.418 ns | 0.2737 ns | 0.2285 ns | 39.410 ns | +| Stackalloc_Long_SkipLocalsInit | 256 | 2.274 ns | 0.0147 ns | 0.0131 ns | 2.274 ns | +| New_Long | 256 | 53.901 ns | 2.9999 ns | 8.4614 ns | 51.449 ns | +| New_Long_SkipLocalsInit | 256 | 53.480 ns | 1.8716 ns | 5.4298 ns | 51.858 ns | +| Stackalloc_Long | 1024 | 137.037 ns | 0.3652 ns | 0.3416 ns | 137.031 ns | +| Stackalloc_Long_SkipLocalsInit | 1024 | 3.669 ns | 0.0254 ns | 0.0226 ns | 3.668 ns | +| New_Long | 1024 | 197.324 ns | 9.2795 ns | 27.0687 ns | 186.588 ns | +| New_Long_SkipLocalsInit | 1024 | 210.996 ns | 10.0255 ns | 27.9471 ns | 206.110 ns | +| Stackalloc_Long | 8192 | 1,897.989 ns | 7.1814 ns | 5.9968 ns | 1,897.814 ns | +| Stackalloc_Long_SkipLocalsInit | 8192 | 20.598 ns | 0.2645 ns | 0.2344 ns | 20.572 ns | +| New_Long | 8192 | 1,324.061 ns | 39.8447 ns | 116.2288 ns | 1,298.794 ns | +| New_Long_SkipLocalsInit | 8192 | 1,305.211 ns | 35.1855 ns | 102.0796 ns | 1,295.539 ns | +*/ + +public class StackallocBenchmarks +{ + private readonly Consumer _consumer = new(); + + [Params(1 << 4, 1 << 8, 1 << 10, 1 << 13)] + public int HashTableSize; + + [Benchmark] + public void Stackalloc_Long() + { + Span hashTable = stackalloc long[HashTableSize]; + + _consumer.Consume(hashTable[0]); + } + + [Benchmark] + [SkipLocalsInit] + public void Stackalloc_Long_SkipLocalsInit() + { + Span hashTable = stackalloc long[HashTableSize]; + + _consumer.Consume(hashTable[0]); + } + + [Benchmark] + public void New_Long() + { + Span hashTable = new long[HashTableSize]; + + _consumer.Consume(hashTable[0]); + } + + + [Benchmark] + [SkipLocalsInit] + public void New_Long_SkipLocalsInit() + { + Span hashTable = new long[HashTableSize]; + + _consumer.Consume(hashTable[0]); + } +} \ No newline at end of file diff --git a/test/DotRecast.Benchmark/Benchmarks/VectorBenchmarks.cs b/test/DotRecast.Benchmark/Benchmarks/VectorBenchmarks.cs new file mode 100644 index 0000000..0cb3faa --- /dev/null +++ b/test/DotRecast.Benchmark/Benchmarks/VectorBenchmarks.cs @@ -0,0 +1,73 @@ +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Engines; +using DotRecast.Core.Numerics; + +namespace DotRecast.Benchmark.Benchmarks; + +/* +| Method | Mean | Error | StdDev | +|------------------ |----------:|----------:|----------:| +| Dot_Vector3 | 0.6395 ns | 0.0125 ns | 0.0104 ns | +| Dot_RcVec3f | 0.2275 ns | 0.0281 ns | 0.0375 ns | +| Cross_Vector3 | 1.1652 ns | 0.0102 ns | 0.0085 ns | +| Cross_RcVec3f | 1.1687 ns | 0.0140 ns | 0.0124 ns | +| Normalize_Vector3 | 1.7964 ns | 0.0173 ns | 0.0162 ns | +| Normalize_RcVec3f | 1.2806 ns | 0.0088 ns | 0.0078 ns | +*/ + +public class VectorBenchmarks +{ + private readonly Consumer _consumer = new(); + + [Benchmark] + public void Dot_Vector3() + { + var v1 = new System.Numerics.Vector3(1, 2, 3); + var v2 = new System.Numerics.Vector3(1, 2, 3); + var v = System.Numerics.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 System.Numerics.Vector3(1, 2, 3); + var v2 = new System.Numerics.Vector3(1, 2, 3); + var v = System.Numerics.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 System.Numerics.Vector3(1, 2, 3); + var v = System.Numerics.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); + } +} \ No newline at end of file diff --git a/test/DotRecast.Benchmark/DotRecast.Benchmark.csproj b/test/DotRecast.Benchmark/DotRecast.Benchmark.csproj index 0a1d580..c284e95 100644 --- a/test/DotRecast.Benchmark/DotRecast.Benchmark.csproj +++ b/test/DotRecast.Benchmark/DotRecast.Benchmark.csproj @@ -2,9 +2,10 @@ Exe - net8.0 - enable - enable + net6.0;net7.0;net8.0 + true + false + true diff --git a/test/DotRecast.Benchmark/Program.cs b/test/DotRecast.Benchmark/Program.cs deleted file mode 100644 index 2ca5fc5..0000000 --- a/test/DotRecast.Benchmark/Program.cs +++ /dev/null @@ -1,7 +0,0 @@ -using BenchmarkDotNet.Running; -using CSharpBencchmark; - -BenchmarkRunner.Run([ - //BenchmarkConverter.TypeToBenchmarks(typeof(Bench_PriorityQueue)), - BenchmarkConverter.TypeToBenchmarks(typeof(Bench_Math_RcVec3f)), -]);