暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

ArrayPerformanceTests.cs 8.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. using NUnit.Framework;
  2. using UnityEngine;
  3. using Unity.Collections.LowLevel.Unsafe;
  4. using Unity.PerformanceTesting;
  5. using Unity.PerformanceTesting.Benchmark;
  6. using System.Runtime.CompilerServices;
  7. using System.Threading;
  8. namespace Unity.Collections.PerformanceTests
  9. {
  10. static class ArrayUtil
  11. {
  12. static public void AllocInt(ref NativeArray<int> container, int capacity, bool addValues)
  13. {
  14. if (capacity >= 0)
  15. {
  16. Random.InitState(0);
  17. container = new NativeArray<int>(capacity, Allocator.Persistent);
  18. if (addValues)
  19. {
  20. for (int i = 0; i < capacity; i++)
  21. container[i] = i;
  22. }
  23. }
  24. else
  25. container.Dispose();
  26. }
  27. static public object AllocBclContainer(int capacity, bool addValues)
  28. {
  29. if (capacity < 0)
  30. return null;
  31. Random.InitState(0);
  32. var bclContainer = new int[capacity];
  33. if (addValues)
  34. {
  35. for (int i = 0; i < capacity; i++)
  36. bclContainer[i] = i;
  37. }
  38. return bclContainer;
  39. }
  40. static public void CreateRandomValues(int capacity, ref UnsafeList<int> values)
  41. {
  42. if (capacity >= 0)
  43. {
  44. values = new UnsafeList<int>(capacity, Allocator.Persistent);
  45. Random.InitState(0);
  46. for (int i = 0; i < capacity; i++)
  47. {
  48. int randKey = Random.Range(0, capacity);
  49. values.Add(randKey);
  50. }
  51. }
  52. else
  53. values.Dispose();
  54. }
  55. }
  56. struct ArrayLength100k : IBenchmarkContainer
  57. {
  58. const int kIterations = 100_000;
  59. NativeArray<int> nativeContainer;
  60. public void AllocNativeContainer(int capacity) => ArrayUtil.AllocInt(ref nativeContainer, capacity, true);
  61. public void AllocUnsafeContainer(int capacity) { }
  62. public object AllocBclContainer(int capacity) => ArrayUtil.AllocBclContainer(capacity, true);
  63. [MethodImpl(MethodImplOptions.NoOptimization)]
  64. public void MeasureNativeContainer()
  65. {
  66. var reader = nativeContainer.AsReadOnly();
  67. for (int i = 0; i < kIterations; i++)
  68. _ = reader.Length;
  69. }
  70. [MethodImpl(MethodImplOptions.NoOptimization)]
  71. public void MeasureUnsafeContainer() { }
  72. [MethodImpl(MethodImplOptions.NoOptimization)]
  73. public void MeasureBclContainer(object container)
  74. {
  75. var bclContainer = (int[])container;
  76. for (int i = 0; i < kIterations; i++)
  77. _ = bclContainer.Length;
  78. }
  79. }
  80. struct ArrayIndexedRead : IBenchmarkContainer
  81. {
  82. NativeArray<int> nativeContainer;
  83. UnsafeList<int> values;
  84. public void AllocNativeContainer(int capacity)
  85. {
  86. ArrayUtil.AllocInt(ref nativeContainer, capacity, true);
  87. ArrayUtil.CreateRandomValues(capacity, ref values);
  88. }
  89. public void AllocUnsafeContainer(int capacity) { }
  90. public object AllocBclContainer(int capacity)
  91. {
  92. object container = ArrayUtil.AllocBclContainer(capacity, true);
  93. ArrayUtil.CreateRandomValues(capacity, ref values);
  94. return container;
  95. }
  96. public void MeasureNativeContainer()
  97. {
  98. var reader = nativeContainer.AsReadOnly();
  99. int insertions = values.Length;
  100. int value = 0;
  101. for (int i = 0; i < insertions; i++)
  102. Volatile.Write(ref value, reader[values[i]]);
  103. }
  104. public void MeasureUnsafeContainer() { }
  105. public void MeasureBclContainer(object container)
  106. {
  107. var bclContainer = (int[])container;
  108. int insertions = values.Length;
  109. int value = 0;
  110. for (int i = 0; i < insertions; i++)
  111. Volatile.Write(ref value, bclContainer[values[i]]);
  112. }
  113. }
  114. struct ArrayIndexedWrite : IBenchmarkContainer
  115. {
  116. NativeArray<int> nativeContainer;
  117. UnsafeList<int> values;
  118. public void AllocNativeContainer(int capacity)
  119. {
  120. ArrayUtil.AllocInt(ref nativeContainer, capacity, true);
  121. ArrayUtil.CreateRandomValues(capacity, ref values);
  122. }
  123. public void AllocUnsafeContainer(int capacity) { }
  124. public object AllocBclContainer(int capacity)
  125. {
  126. object container = ArrayUtil.AllocBclContainer(capacity, true);
  127. ArrayUtil.CreateRandomValues(capacity, ref values);
  128. return container;
  129. }
  130. public void MeasureNativeContainer()
  131. {
  132. int insertions = values.Length;
  133. for (int i = 0; i < insertions; i++)
  134. nativeContainer[values[i]] = i;
  135. }
  136. public void MeasureUnsafeContainer() { }
  137. public void MeasureBclContainer(object container)
  138. {
  139. var bclContainer = (int[])container;
  140. int insertions = values.Length;
  141. for (int i = 0; i < insertions; i++)
  142. bclContainer[values[i]] = i;
  143. }
  144. }
  145. struct ArrayForEach : IBenchmarkContainer
  146. {
  147. NativeArray<int> nativeContainer;
  148. public int total;
  149. public void AllocNativeContainer(int capacity) => ArrayUtil.AllocInt(ref nativeContainer, capacity, true);
  150. public void AllocUnsafeContainer(int capacity) { }
  151. public object AllocBclContainer(int capacity) => ArrayUtil.AllocBclContainer(capacity, true);
  152. public void MeasureNativeContainer()
  153. {
  154. int value = 0;
  155. foreach (var element in nativeContainer)
  156. Volatile.Write(ref value, element);
  157. }
  158. public void MeasureUnsafeContainer() { }
  159. public void MeasureBclContainer(object container)
  160. {
  161. int value = 0;
  162. var bclContainer = (int[])container;
  163. foreach (var element in bclContainer)
  164. Volatile.Write(ref value, element);
  165. }
  166. }
  167. [Benchmark(typeof(BenchmarkContainerType), true)]
  168. class Array
  169. {
  170. #if UNITY_EDITOR
  171. [UnityEditor.MenuItem(BenchmarkContainerConfig.kMenuItemIndividual + nameof(Array))]
  172. static void RunIndividual()
  173. => BenchmarkContainerConfig.RunBenchmark(typeof(Array));
  174. #endif
  175. [Test, Performance]
  176. [Category("Performance")]
  177. public unsafe void Length_x_100k(
  178. [Values(0, 100)] int capacity,
  179. [Values(BenchmarkContainerType.Native, BenchmarkContainerType.NativeBurstSafety,
  180. BenchmarkContainerType.NativeBurstNoSafety)] BenchmarkContainerType type)
  181. {
  182. BenchmarkContainerRunner<ArrayLength100k>.Run(capacity, type);
  183. }
  184. [Test, Performance]
  185. [Category("Performance")]
  186. public unsafe void IndexedRead(
  187. [Values(10000, 100000, 1000000)] int insertions,
  188. [Values(BenchmarkContainerType.Native, BenchmarkContainerType.NativeBurstSafety,
  189. BenchmarkContainerType.NativeBurstNoSafety)] BenchmarkContainerType type)
  190. {
  191. BenchmarkContainerRunner<ArrayIndexedRead>.Run(insertions, type);
  192. }
  193. [Test, Performance]
  194. [Category("Performance")]
  195. public unsafe void IndexedWrite(
  196. [Values(10000, 100000, 1000000)] int insertions,
  197. [Values(BenchmarkContainerType.Native, BenchmarkContainerType.NativeBurstSafety,
  198. BenchmarkContainerType.NativeBurstNoSafety)] BenchmarkContainerType type)
  199. {
  200. BenchmarkContainerRunner<ArrayIndexedWrite>.Run(insertions, type);
  201. }
  202. [Test, Performance]
  203. [Category("Performance")]
  204. public unsafe void Foreach(
  205. [Values(10000, 100000, 1000000)] int insertions,
  206. [Values(BenchmarkContainerType.Native, BenchmarkContainerType.NativeBurstSafety,
  207. BenchmarkContainerType.NativeBurstNoSafety)] BenchmarkContainerType type)
  208. {
  209. BenchmarkContainerRunner<ArrayForEach>.Run(insertions, type);
  210. }
  211. }
  212. }