com.wallstop-studios.unity-helpers 2.0.0-rc78.2 → 2.0.0-rc78.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -11
- package/Runtime/Core/Extension/IListExtensions.cs +95 -1
- package/Runtime/Core/Random/PRNG.cs +1 -1
- package/Runtime/Core/Random/XoroShiroEnhancedRandom.cs +108 -0
- package/Runtime/Core/Random/XoroShiroEnhancedRandom.cs.meta +3 -0
- package/Runtime/Core/Random/{XorShiroRandom.cs → XoroShiroRandom.cs} +13 -13
- package/Tests/Runtime/Extensions/IListExtensionTests.cs +65 -0
- package/Tests/Runtime/Performance/ListExtensionPerformanceTests.cs +80 -0
- package/Tests/Runtime/Performance/ListExtensionPerformanceTests.cs.meta +3 -0
- package/Tests/Runtime/Performance/RandomPerformanceTests.cs +10 -9
- package/Tests/Runtime/Random/XoroShiroEnhancedRandomTests.cs +12 -0
- package/Tests/Runtime/Random/XoroShiroEnhancedRandomTests.cs.meta +3 -0
- package/Tests/Runtime/Random/XoroShiroRandomTests.cs +9 -0
- package/package.json +1 -59
- package/Tests/Runtime/Random/XorShiroRandomTests.cs +0 -9
- /package/Runtime/Core/Random/{XorShiroRandom.cs.meta → XoroShiroRandom.cs.meta} +0 -0
- /package/Tests/Runtime/Random/{XorShiroRandomTests.cs.meta → XoroShiroRandomTests.cs.meta} +0 -0
package/README.md
CHANGED
|
@@ -133,17 +133,18 @@ random.NextNoiseMap(width, height); // A configurable noise map generated using
|
|
|
133
133
|
|
|
134
134
|
| Random | NextBool | Next | NextUInt | NextFloat | NextDouble | NextUint - Range | NextInt - Range |
|
|
135
135
|
| ------ | -------- | ---- | -------- | --------- | ---------- | ---------------- | --------------- |
|
|
136
|
-
|
|
|
137
|
-
|
|
|
138
|
-
|
|
|
139
|
-
|
|
|
140
|
-
|
|
|
141
|
-
|
|
|
142
|
-
|
|
|
143
|
-
|
|
|
144
|
-
|
|
|
145
|
-
|
|
|
146
|
-
|
|
|
136
|
+
| DotNetRandom | 30,700,000 | 30,900,000 | 32,600,000 | 25,700,000 | 25,800,000 |19,500,000 |18,200,000 |
|
|
137
|
+
| LinearCongruentialGenerator | 179,600,000 | 179,700,000 | 256,600,000 | 91,400,000 | 92,000,000 |43,600,000 |39,600,000 |
|
|
138
|
+
| PcgRandom | 168,400,000 | 168,400,000 | 234,200,000 | 88,800,000 | 89,300,000 |43,000,000 |38,700,000 |
|
|
139
|
+
| RomuDuo | 134,600,000 | 134,700,000 | 173,800,000 | 78,200,000 | 78,800,000 |39,900,000 |36,200,000 |
|
|
140
|
+
| SplitMix64 | 163,200,000 | 163,300,000 | 224,400,000 | 87,600,000 | 87,900,000 |42,600,000 |38,700,000 |
|
|
141
|
+
| SquirrelRandom | 128,300,000 | 128,400,000 | 163,200,000 | 75,800,000 | 76,600,000 |39,500,000 |36,200,000 |
|
|
142
|
+
| SystemRandom | 77,800,000 | 88,800,000 | 37,600,000 | 70,500,000 | 69,600,000 |38,200,000 |34,300,000 |
|
|
143
|
+
| UnityRandom | 53,000,000 | 53,100,000 | 58,300,000 | 41,400,000 | 41,400,000 |26,700,000 |24,900,000 |
|
|
144
|
+
| WyRandom | 79,100,000 | 79,100,000 | 91,100,000 | 53,000,000 | 55,300,000 |32,100,000 |30,000,000 |
|
|
145
|
+
| XorShiftRandom | 179,500,000 | 179,500,000 | 256,500,000 | 92,000,000 | 92,400,000 |42,400,000 |38,500,000 |
|
|
146
|
+
| XoroShiroRandom | 103,600,000 | 103,700,000 | 125,300,000 | 66,200,000 | 67,000,000 |36,900,000 |34,000,000 |
|
|
147
|
+
| XoroShiroEnhancedRandom | 149,700,000 | 149,700,000 | 199,700,000 | 83,000,000 | 83,800,000 |41,400,000 |37,700,000 |
|
|
147
148
|
|
|
148
149
|
# Spatial Trees
|
|
149
150
|
There are three implemented 2D immutable spatial trees that can store generic objects, as long as there is some resolution function that can convert them into Vector2 spatial positions.
|
|
@@ -2,10 +2,18 @@
|
|
|
2
2
|
{
|
|
3
3
|
using System;
|
|
4
4
|
using System.Collections.Generic;
|
|
5
|
+
using System.ComponentModel;
|
|
6
|
+
using System.Diagnostics.Contracts;
|
|
5
7
|
using Helper;
|
|
6
8
|
using Random;
|
|
7
9
|
using Utils;
|
|
8
10
|
|
|
11
|
+
public enum SortAlgorithm
|
|
12
|
+
{
|
|
13
|
+
ShellEnhanced = 0,
|
|
14
|
+
Insertion = 1,
|
|
15
|
+
}
|
|
16
|
+
|
|
9
17
|
public static class IListExtensions
|
|
10
18
|
{
|
|
11
19
|
public static void Shuffle<T>(this IList<T> list, IRandom random = null)
|
|
@@ -87,6 +95,36 @@
|
|
|
87
95
|
list.RemoveAt(lastIndex);
|
|
88
96
|
}
|
|
89
97
|
|
|
98
|
+
public static void Sort<T, TComparer>(
|
|
99
|
+
this IList<T> array,
|
|
100
|
+
TComparer comparer,
|
|
101
|
+
SortAlgorithm sortAlgorithm = SortAlgorithm.ShellEnhanced
|
|
102
|
+
)
|
|
103
|
+
where TComparer : IComparer<T>
|
|
104
|
+
{
|
|
105
|
+
switch (sortAlgorithm)
|
|
106
|
+
{
|
|
107
|
+
case SortAlgorithm.ShellEnhanced:
|
|
108
|
+
{
|
|
109
|
+
ShellSortEnhanced(array, comparer);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
case SortAlgorithm.Insertion:
|
|
113
|
+
{
|
|
114
|
+
InsertionSort(array, comparer);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
default:
|
|
118
|
+
{
|
|
119
|
+
throw new InvalidEnumArgumentException(
|
|
120
|
+
nameof(sortAlgorithm),
|
|
121
|
+
(int)sortAlgorithm,
|
|
122
|
+
typeof(SortAlgorithm)
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
90
128
|
public static void InsertionSort<T, TComparer>(this IList<T> array, TComparer comparer)
|
|
91
129
|
where TComparer : IComparer<T>
|
|
92
130
|
{
|
|
@@ -104,6 +142,61 @@
|
|
|
104
142
|
}
|
|
105
143
|
}
|
|
106
144
|
|
|
145
|
+
/*
|
|
146
|
+
Implementation copyright Will Stafford Parsons,
|
|
147
|
+
https://github.com/wstaffordp/bsearch-enhanced/blob/master/examples/benchmark.c#L31-L78
|
|
148
|
+
|
|
149
|
+
Please contact the original author if you would like an explanation of constants.
|
|
150
|
+
*/
|
|
151
|
+
public static void ShellSortEnhanced<T, TComparer>(this IList<T> array, TComparer comparer)
|
|
152
|
+
where TComparer : IComparer<T>
|
|
153
|
+
{
|
|
154
|
+
int length = array.Count;
|
|
155
|
+
int gap = array.Count;
|
|
156
|
+
|
|
157
|
+
int i;
|
|
158
|
+
int j;
|
|
159
|
+
while (gap > 15)
|
|
160
|
+
{
|
|
161
|
+
gap = (gap >> 5) + (gap >> 3);
|
|
162
|
+
i = gap;
|
|
163
|
+
|
|
164
|
+
while (i < length)
|
|
165
|
+
{
|
|
166
|
+
T element = array[i];
|
|
167
|
+
j = i;
|
|
168
|
+
while (j >= gap && 0 < comparer.Compare(array[j - gap], element))
|
|
169
|
+
{
|
|
170
|
+
array[j] = array[j - gap];
|
|
171
|
+
j -= gap;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
array[j] = element;
|
|
175
|
+
i++;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
i = 1;
|
|
180
|
+
gap = 0;
|
|
181
|
+
|
|
182
|
+
while (i < length)
|
|
183
|
+
{
|
|
184
|
+
T element = array[i];
|
|
185
|
+
j = i;
|
|
186
|
+
|
|
187
|
+
while (j > 0 && 0 < comparer.Compare(array[gap], element))
|
|
188
|
+
{
|
|
189
|
+
array[j] = array[gap];
|
|
190
|
+
j = gap;
|
|
191
|
+
gap--;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
array[j] = element;
|
|
195
|
+
gap = i;
|
|
196
|
+
i++;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
107
200
|
public static void SortByName<T>(this IList<T> inputList)
|
|
108
201
|
where T : UnityEngine.Object
|
|
109
202
|
{
|
|
@@ -121,12 +214,13 @@
|
|
|
121
214
|
}
|
|
122
215
|
default:
|
|
123
216
|
{
|
|
124
|
-
inputList.
|
|
217
|
+
inputList.Sort(UnityObjectNameComparer<T>.Instance);
|
|
125
218
|
break;
|
|
126
219
|
}
|
|
127
220
|
}
|
|
128
221
|
}
|
|
129
222
|
|
|
223
|
+
[Pure]
|
|
130
224
|
public static bool IsSorted<T>(this IList<T> list, IComparer<T> comparer = null)
|
|
131
225
|
{
|
|
132
226
|
if (list.Count <= 1)
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/*
|
|
2
|
+
XoroShiroEnhanced is a significant enhancement upon the classic XoroShiroRandom discovered by Will Stafford Parsons.
|
|
3
|
+
|
|
4
|
+
Reference: https://github.com/wstaffordp/bsearch-enhanced/blob/master/examples/benchmark.c#L4-L29
|
|
5
|
+
|
|
6
|
+
Copyright original author: https://github.com/wstaffordp
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
namespace WallstopStudios.UnityHelpers.Core.Random
|
|
10
|
+
{
|
|
11
|
+
using System;
|
|
12
|
+
using System.Runtime.Serialization;
|
|
13
|
+
using System.Text.Json.Serialization;
|
|
14
|
+
|
|
15
|
+
[Serializable]
|
|
16
|
+
[DataContract]
|
|
17
|
+
public sealed class XoroShiroEnhancedRandom : AbstractRandom
|
|
18
|
+
{
|
|
19
|
+
private const int UintByteCount = sizeof(uint) * 8;
|
|
20
|
+
|
|
21
|
+
public static XoroShiroEnhancedRandom Instance =>
|
|
22
|
+
ThreadLocalRandom<XoroShiroEnhancedRandom>.Instance;
|
|
23
|
+
|
|
24
|
+
public override RandomState InternalState
|
|
25
|
+
{
|
|
26
|
+
get
|
|
27
|
+
{
|
|
28
|
+
ulong stateA = ((ulong)_a << UintByteCount) | _b;
|
|
29
|
+
ulong stateB = ((ulong)_c << UintByteCount) | _d;
|
|
30
|
+
byte[] eBytes = BitConverter.GetBytes(_e);
|
|
31
|
+
Array.Resize(ref eBytes, sizeof(double));
|
|
32
|
+
Array.Fill<byte>(eBytes, 0, sizeof(uint), sizeof(double) - sizeof(uint));
|
|
33
|
+
return new RandomState(stateA, stateB, BitConverter.ToDouble(eBytes, 0));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private uint _a;
|
|
38
|
+
private uint _b;
|
|
39
|
+
private uint _c;
|
|
40
|
+
private uint _d;
|
|
41
|
+
private uint _e;
|
|
42
|
+
|
|
43
|
+
public XoroShiroEnhancedRandom()
|
|
44
|
+
: this(Guid.NewGuid()) { }
|
|
45
|
+
|
|
46
|
+
public XoroShiroEnhancedRandom(Guid guid, uint? extraSeed = null)
|
|
47
|
+
{
|
|
48
|
+
byte[] guidArray = guid.ToByteArray();
|
|
49
|
+
_a = BitConverter.ToUInt32(guidArray, 0);
|
|
50
|
+
_b = BitConverter.ToUInt32(guidArray, sizeof(uint));
|
|
51
|
+
_c = BitConverter.ToUInt32(guidArray, sizeof(uint) * 2);
|
|
52
|
+
_d = BitConverter.ToUInt32(guidArray, sizeof(uint) * 3);
|
|
53
|
+
_e = extraSeed ?? unchecked((uint)guid.GetHashCode());
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
[JsonConstructor]
|
|
57
|
+
public XoroShiroEnhancedRandom(RandomState internalState)
|
|
58
|
+
{
|
|
59
|
+
unchecked
|
|
60
|
+
{
|
|
61
|
+
_a = (uint)(internalState.State1 >> UintByteCount);
|
|
62
|
+
_b = (uint)internalState.State1;
|
|
63
|
+
_c = (uint)(internalState.State2 >> UintByteCount);
|
|
64
|
+
_d = (uint)internalState.State2;
|
|
65
|
+
double? gaussian = internalState.Gaussian;
|
|
66
|
+
if (gaussian != null)
|
|
67
|
+
{
|
|
68
|
+
byte[] eBytes = BitConverter.GetBytes(gaussian.Value);
|
|
69
|
+
Array.Resize(ref eBytes, sizeof(uint));
|
|
70
|
+
_e = BitConverter.ToUInt32(eBytes, 0);
|
|
71
|
+
}
|
|
72
|
+
else
|
|
73
|
+
{
|
|
74
|
+
throw new InvalidOperationException(
|
|
75
|
+
$"{nameof(XoroShiroEnhancedRandom)} requires a Gaussian state."
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
public override uint NextUint()
|
|
82
|
+
{
|
|
83
|
+
unchecked
|
|
84
|
+
{
|
|
85
|
+
uint result = _b + _e;
|
|
86
|
+
++_a;
|
|
87
|
+
if (_a == 0U)
|
|
88
|
+
{
|
|
89
|
+
_c += _e;
|
|
90
|
+
_d ^= _b;
|
|
91
|
+
_b += _c;
|
|
92
|
+
_e ^= _d;
|
|
93
|
+
return result;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
_b = ((_b << 17) | (_b >> 15)) ^ _d;
|
|
97
|
+
_d += 1111111111U;
|
|
98
|
+
_e = (result << 13) | (result >> 19);
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
public override IRandom Copy()
|
|
104
|
+
{
|
|
105
|
+
return new XoroShiroEnhancedRandom(InternalState);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -6,37 +6,37 @@
|
|
|
6
6
|
using Extension;
|
|
7
7
|
using Helper;
|
|
8
8
|
|
|
9
|
-
public sealed class
|
|
9
|
+
public sealed class XoroShiroRandom
|
|
10
10
|
: AbstractRandom,
|
|
11
|
-
IEquatable<
|
|
11
|
+
IEquatable<XoroShiroRandom>,
|
|
12
12
|
IComparable,
|
|
13
|
-
IComparable<
|
|
13
|
+
IComparable<XoroShiroRandom>
|
|
14
14
|
{
|
|
15
|
-
public static
|
|
15
|
+
public static XoroShiroRandom Instance => ThreadLocalRandom<XoroShiroRandom>.Instance;
|
|
16
16
|
|
|
17
17
|
public override RandomState InternalState => new(_s0, _s1, _cachedGaussian);
|
|
18
18
|
|
|
19
19
|
internal ulong _s0;
|
|
20
20
|
internal ulong _s1;
|
|
21
21
|
|
|
22
|
-
public
|
|
22
|
+
public XoroShiroRandom()
|
|
23
23
|
: this(Guid.NewGuid()) { }
|
|
24
24
|
|
|
25
|
-
public
|
|
25
|
+
public XoroShiroRandom(Guid guid)
|
|
26
26
|
{
|
|
27
27
|
byte[] bytes = guid.ToByteArray();
|
|
28
28
|
_s0 = BitConverter.ToUInt64(bytes, 0);
|
|
29
29
|
_s1 = BitConverter.ToUInt64(bytes, 8);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
public
|
|
32
|
+
public XoroShiroRandom(ulong seed1, ulong seed2)
|
|
33
33
|
{
|
|
34
34
|
_s0 = seed1;
|
|
35
35
|
_s1 = seed2;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
[JsonConstructor]
|
|
39
|
-
public
|
|
39
|
+
public XoroShiroRandom(RandomState internalState)
|
|
40
40
|
{
|
|
41
41
|
_s0 = internalState.State1;
|
|
42
42
|
_s1 = internalState.State2;
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
|
|
62
62
|
public override IRandom Copy()
|
|
63
63
|
{
|
|
64
|
-
return new
|
|
64
|
+
return new XoroShiroRandom(InternalState);
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
@@ -72,10 +72,10 @@
|
|
|
72
72
|
|
|
73
73
|
public override bool Equals(object obj)
|
|
74
74
|
{
|
|
75
|
-
return Equals(obj as
|
|
75
|
+
return Equals(obj as XoroShiroRandom);
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
public bool Equals(
|
|
78
|
+
public bool Equals(XoroShiroRandom other)
|
|
79
79
|
{
|
|
80
80
|
if (other == null)
|
|
81
81
|
{
|
|
@@ -97,10 +97,10 @@
|
|
|
97
97
|
|
|
98
98
|
public int CompareTo(object obj)
|
|
99
99
|
{
|
|
100
|
-
return CompareTo(obj as
|
|
100
|
+
return CompareTo(obj as XoroShiroRandom);
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
public int CompareTo(
|
|
103
|
+
public int CompareTo(XoroShiroRandom other)
|
|
104
104
|
{
|
|
105
105
|
if (other == null)
|
|
106
106
|
{
|
|
@@ -100,5 +100,70 @@
|
|
|
100
100
|
Assert.That(input.OrderBy(x => x), Is.EqualTo(insertionSorted));
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
|
+
|
|
104
|
+
[Test]
|
|
105
|
+
public void ShellSortEnhanced()
|
|
106
|
+
{
|
|
107
|
+
for (int i = 0; i < NumTries; ++i)
|
|
108
|
+
{
|
|
109
|
+
int[] input = Enumerable
|
|
110
|
+
.Range(0, 100)
|
|
111
|
+
.Select(_ => PRNG.Instance.Next(int.MinValue, int.MaxValue))
|
|
112
|
+
.ToArray();
|
|
113
|
+
int[] conventionalSorted = input.ToArray();
|
|
114
|
+
Array.Sort(conventionalSorted);
|
|
115
|
+
|
|
116
|
+
int[] insertionSorted = input.ToArray();
|
|
117
|
+
insertionSorted.ShellSortEnhanced(new IntComparer());
|
|
118
|
+
Assert.That(conventionalSorted, Is.EqualTo(insertionSorted));
|
|
119
|
+
Assert.That(input.OrderBy(x => x), Is.EqualTo(insertionSorted));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
[Test]
|
|
124
|
+
public void SortDefaultAlgorithm()
|
|
125
|
+
{
|
|
126
|
+
for (int i = 0; i < NumTries; ++i)
|
|
127
|
+
{
|
|
128
|
+
int[] input = Enumerable
|
|
129
|
+
.Range(0, 100)
|
|
130
|
+
.Select(_ => PRNG.Instance.Next(int.MinValue, int.MaxValue))
|
|
131
|
+
.ToArray();
|
|
132
|
+
int[] conventionalSorted = input.ToArray();
|
|
133
|
+
Array.Sort(conventionalSorted);
|
|
134
|
+
|
|
135
|
+
int[] insertionSorted = input.ToArray();
|
|
136
|
+
insertionSorted.Sort(new IntComparer());
|
|
137
|
+
Assert.That(conventionalSorted, Is.EqualTo(insertionSorted));
|
|
138
|
+
Assert.That(input.OrderBy(x => x), Is.EqualTo(insertionSorted));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
[Test]
|
|
143
|
+
public void SortAllAlgorithms()
|
|
144
|
+
{
|
|
145
|
+
SortAlgorithm[] sortAlgorithms = Enum.GetValues(typeof(SortAlgorithm))
|
|
146
|
+
.OfType<SortAlgorithm>()
|
|
147
|
+
.ToArray();
|
|
148
|
+
Assert.That(sortAlgorithms.Length, Is.GreaterThan(0));
|
|
149
|
+
|
|
150
|
+
foreach (SortAlgorithm sortAlgorithm in sortAlgorithms)
|
|
151
|
+
{
|
|
152
|
+
for (int i = 0; i < NumTries; ++i)
|
|
153
|
+
{
|
|
154
|
+
int[] input = Enumerable
|
|
155
|
+
.Range(0, 100)
|
|
156
|
+
.Select(_ => PRNG.Instance.Next(int.MinValue, int.MaxValue))
|
|
157
|
+
.ToArray();
|
|
158
|
+
int[] conventionalSorted = input.ToArray();
|
|
159
|
+
Array.Sort(conventionalSorted);
|
|
160
|
+
|
|
161
|
+
int[] insertionSorted = input.ToArray();
|
|
162
|
+
insertionSorted.Sort(new IntComparer(), sortAlgorithm);
|
|
163
|
+
Assert.That(conventionalSorted, Is.EqualTo(insertionSorted));
|
|
164
|
+
Assert.That(input.OrderBy(x => x), Is.EqualTo(insertionSorted));
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
103
168
|
}
|
|
104
169
|
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
namespace WallstopStudios.UnityHelpers.Tests.Performance
|
|
2
|
+
{
|
|
3
|
+
using System;
|
|
4
|
+
using System.Collections.Generic;
|
|
5
|
+
using System.Diagnostics;
|
|
6
|
+
using System.Linq;
|
|
7
|
+
using NUnit.Framework;
|
|
8
|
+
using WallstopStudios.UnityHelpers.Core.Extension;
|
|
9
|
+
using WallstopStudios.UnityHelpers.Core.Random;
|
|
10
|
+
|
|
11
|
+
public sealed class ListExtensionPerformanceTests
|
|
12
|
+
{
|
|
13
|
+
private sealed class IntComparer : IComparer<int>
|
|
14
|
+
{
|
|
15
|
+
public static readonly IntComparer Instance = new();
|
|
16
|
+
|
|
17
|
+
private IntComparer() { }
|
|
18
|
+
|
|
19
|
+
public int Compare(int x, int y)
|
|
20
|
+
{
|
|
21
|
+
return x.CompareTo(y);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
[Test]
|
|
26
|
+
public void SortPerformanceTest()
|
|
27
|
+
{
|
|
28
|
+
const int NumInvocationsPerIteration = 100;
|
|
29
|
+
TimeSpan timeout = TimeSpan.FromSeconds(2.5);
|
|
30
|
+
|
|
31
|
+
PcgRandom random = new(123456);
|
|
32
|
+
|
|
33
|
+
List<int> list = Enumerable.Range(0, 1_000).ToList();
|
|
34
|
+
list.Shuffle(random);
|
|
35
|
+
|
|
36
|
+
int reference = RunTest(list, Array.Sort, timeout);
|
|
37
|
+
int insertionSort = RunTest(
|
|
38
|
+
list,
|
|
39
|
+
input => input.InsertionSort(IntComparer.Instance),
|
|
40
|
+
timeout
|
|
41
|
+
);
|
|
42
|
+
int shellSort = RunTest(
|
|
43
|
+
list,
|
|
44
|
+
input => input.ShellSortEnhanced(IntComparer.Instance),
|
|
45
|
+
timeout
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
UnityEngine.Debug.Log("| Operation | Operations / Second |");
|
|
49
|
+
UnityEngine.Debug.Log($"| Reference | {reference / timeout.TotalSeconds:N0} |");
|
|
50
|
+
UnityEngine.Debug.Log($"| InsertionSort | {insertionSort / timeout.TotalSeconds:N0} |");
|
|
51
|
+
UnityEngine.Debug.Log($"| ShellSort | {shellSort / timeout.TotalSeconds:N0} |");
|
|
52
|
+
return;
|
|
53
|
+
|
|
54
|
+
static int RunTest(List<int> input, Action<int[]> sorter, TimeSpan timeout)
|
|
55
|
+
{
|
|
56
|
+
int[] copy = input.ToArray();
|
|
57
|
+
int length = input.Count;
|
|
58
|
+
|
|
59
|
+
int[] toBeSorted = input.ToArray();
|
|
60
|
+
sorter(toBeSorted);
|
|
61
|
+
Assert.IsTrue(toBeSorted.IsSorted());
|
|
62
|
+
Array.Copy(copy, toBeSorted, length);
|
|
63
|
+
|
|
64
|
+
int count = 0;
|
|
65
|
+
Stopwatch timer = Stopwatch.StartNew();
|
|
66
|
+
do
|
|
67
|
+
{
|
|
68
|
+
for (int i = 0; i < NumInvocationsPerIteration; ++i)
|
|
69
|
+
{
|
|
70
|
+
sorter(toBeSorted);
|
|
71
|
+
Array.Copy(copy, toBeSorted, length);
|
|
72
|
+
++count;
|
|
73
|
+
}
|
|
74
|
+
} while (timer.Elapsed < timeout);
|
|
75
|
+
|
|
76
|
+
return count;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
public sealed class RandomPerformanceTests
|
|
9
9
|
{
|
|
10
|
-
private const int NumInvocationsPerIteration =
|
|
10
|
+
private const int NumInvocationsPerIteration = 100_000;
|
|
11
11
|
|
|
12
12
|
[Test]
|
|
13
13
|
public void Benchmark()
|
|
@@ -21,17 +21,18 @@
|
|
|
21
21
|
"| ------ | -------- | ---- | -------- | --------- | ---------- | ---------------- | --------------- |"
|
|
22
22
|
);
|
|
23
23
|
|
|
24
|
-
RunTest(new PcgRandom(), timeout);
|
|
25
|
-
RunTest(new SystemRandom(), timeout);
|
|
26
|
-
RunTest(new SquirrelRandom(), timeout);
|
|
27
|
-
RunTest(new XorShiftRandom(), timeout);
|
|
28
24
|
RunTest(new DotNetRandom(), timeout);
|
|
29
|
-
RunTest(new
|
|
30
|
-
RunTest(new
|
|
25
|
+
RunTest(new LinearCongruentialGenerator(), timeout);
|
|
26
|
+
RunTest(new PcgRandom(), timeout);
|
|
31
27
|
RunTest(new RomuDuo(), timeout);
|
|
32
|
-
RunTest(new
|
|
28
|
+
RunTest(new SplitMix64(), timeout);
|
|
29
|
+
RunTest(new SquirrelRandom(), timeout);
|
|
30
|
+
RunTest(new SystemRandom(), timeout);
|
|
33
31
|
RunTest(new UnityRandom(), timeout);
|
|
34
|
-
RunTest(new
|
|
32
|
+
RunTest(new WyRandom(), timeout);
|
|
33
|
+
RunTest(new XorShiftRandom(), timeout);
|
|
34
|
+
RunTest(new XoroShiroRandom(), timeout);
|
|
35
|
+
RunTest(new XoroShiroEnhancedRandom(), timeout);
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
private static void RunTest<T>(T random, TimeSpan timeout)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
namespace WallstopStudios.UnityHelpers.Tests.Random
|
|
2
|
+
{
|
|
3
|
+
using WallstopStudios.UnityHelpers.Core.Random;
|
|
4
|
+
|
|
5
|
+
public sealed class XoroShiroEnhancedRandomTests : RandomTestBase
|
|
6
|
+
{
|
|
7
|
+
protected override IRandom NewRandom()
|
|
8
|
+
{
|
|
9
|
+
return new XoroShiroEnhancedRandom();
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "com.wallstop-studios.unity-helpers",
|
|
3
|
-
"version": "2.0.0-rc78.
|
|
3
|
+
"version": "2.0.0-rc78.4",
|
|
4
4
|
"displayName": "Unity Helpers",
|
|
5
5
|
"description": "Various Unity Helper Library",
|
|
6
6
|
"dependencies": {},
|
|
@@ -38,61 +38,3 @@
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
File without changes
|
|
File without changes
|