{"id":348353,"date":"2023-06-04T03:00:13","date_gmt":"2023-06-04T03:00:13","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=348353"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=348353","title":{"rendered":"<span>\u0411\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0430\u044f Array Reverse: \u043a\u0430\u043a \u0431\u044b\u0441\u0442\u0440\u043e \u043f\u0435\u0440\u0435\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432?<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<p>\u0423\u0432\u0430\u0436\u0430\u0435\u043c\u044b\u0435 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0438, \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u0442\u0435\u0441\u0442\u0430\u0445 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0441\u0432\u043e\u0438 \u0432\u044b\u0432\u043e\u0434\u044b. \u0422\u0435\u0441\u0442\u044b \u0441\u0434\u0435\u043b\u0430\u043d\u044b \u043d\u0430 .net 7.<\/p>\n<p>\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043b \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c BenchmarkDotNet, \u0442\u0430\u043a \u0447\u0442\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u0432\u044b\u0432\u043e\u0434\u044b.<\/p>\n<p>\u0421\u0440\u0430\u0437\u0443 \u043e\u0442\u043c\u0435\u0447\u0443, \u0447\u0442\u043e \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0430\u0442\u0440\u0438\u0431\u0443\u0442 [GlobalSetup], \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0435 \u043f\u0435\u0440\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u043e \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u00abExecuted once per each N value\u00bb \u0438 \u044d\u0442\u043e \u043d\u0430\u043c \u0438 \u043d\u0430\u0434\u043e.<\/p>\n<p>\u0414\u043b\u044f \u043f\u043e\u043b\u043d\u043e\u0439 \u043a\u0430\u0440\u0442\u0438\u043d\u044b \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0442\u0435\u0441\u0442\u044b \u0438\u0434\u0443\u0442 \u043d\u0430 \u043c\u0430\u0441\u0441\u0438\u0432\u0430\u0445 \u0441 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 1000, 10_000, 100_000, 1_000_000, 100_000_000, \u0430 \u0441\u0430\u043c\u044b\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0441 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u0434\u043e 1_000_000_000 \u0447\u0438\u0441\u0435\u043b.<\/p>\n<p>\u041f\u0435\u0440\u0432\u044b\u0435 \u0442\u0435\u0441\u0442\u044b \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u0441 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0431\u0435\u0437 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e, \u0447\u0442\u043e \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u0435\u0440\u043d\u044b\u0439 \u0432\u044b\u0431\u043e\u0440, \u043d\u043e \u043f\u0430\u043c\u044f\u0442\u0438 \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 (\u0442\u0435\u0441\u0442\u044b \u043f\u043e\u043a\u0430\u0436\u0443\u0442 \u0441\u0442\u0440\u0430\u043d\u043d\u043e\u0441\u0442\u044c \u043d\u0430 \u043a\u0440\u0443\u043f\u043d\u043e\u0439 \u0432\u044b\u0431\u043e\u0440\u043a\u0435).<\/p>\n<p>\u0414\u043b\u044f \u0441\u0442\u0430\u0440\u0442\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0431\u044b\u0447\u043d\u044b\u0439 While, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u0432 \u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438, \u0447\u0435\u043c \u0430\u043d\u0430\u043b\u043e\u0433\u0438 \u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u043e\u0440\u0430\u0445 \u0441\u0435\u0442\u0438:<\/p>\n<pre><code class=\"cs\">    [Benchmark]     public int[] While()     {         if (array.Length == 0)         {             return Array.Empty&lt;int&gt;();         }          int i = -1;         int j = array.Length;          while (i++ &lt; j--)         {             int temp = array[i];             array[i] = array[j];             array[j] = temp;         }          return array;     }<\/code><\/pre>\n<p>\u0421\u0430\u043c\u044b\u0439 \u0447\u0430\u0441\u0442\u043e \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u0435\u043c\u044b\u0439 \u043e\u0442\u0432\u0435\u0442 \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441:<\/p>\n<pre><code class=\"cs\">    [Benchmark]     public int[] Array_Reverse()     {         Array.Reverse(array);         return array;     }<\/code><\/pre>\n<p>\u041d\u0435 \u0441\u043a\u0430\u0436\u0443, \u0447\u0442\u043e \u0442\u0443\u0442 \u0432\u0441\u0435 \u043f\u043b\u043e\u0445\u043e, \u0432\u0435\u0434\u044c \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c \u0442\u0430\u043c \u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0431\u043e\u0442\u044b \u0441 unsafe \u0438 \u0440\u0430\u0437\u043d\u043e\u0439 \u00ab\u043c\u0430\u0433\u0438\u0438\u00bb \u0434\u043b\u044f \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"cs\">public unsafe static void Reverse&lt;[Nullable(2)] T&gt;(T[] array) { if (array == null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array); } if (array.Length &gt; 1) { SpanHelpers.Reverse(ref MemoryMarshal.GetArrayDataReference(array), (UIntPtr)(void*)array.Length); } }  [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Reverse&lt;T&gt;(ref T elements, UIntPtr length) { if (!RuntimeHelpers.IsReferenceOrContainsReferences&lt;T&gt;()) { if (Unsafe.SizeOf&lt;T&gt;() == 1) { Reverse(ref Unsafe.As&lt;T, byte&gt;(ref elements), length); return; } if (Unsafe.SizeOf&lt;T&gt;() == 2) { Reverse(ref Unsafe.As&lt;T, char&gt;(ref elements), length); return; } if (Unsafe.SizeOf&lt;T&gt;() == 4) { Reverse(ref Unsafe.As&lt;T, int&gt;(ref elements), length); return; } if (Unsafe.SizeOf&lt;T&gt;() == 8) { Reverse(ref Unsafe.As&lt;T, long&gt;(ref elements), length); return; } } ReverseInner(ref elements, length); }  public unsafe static void Reverse(ref long buf, UIntPtr length) { if (Avx2.IsSupported &amp;&amp; (ulong)(UIntPtr)(void*)((long)Vector256&lt;long&gt;.Count * 2L) &lt;= (ulong)length) { UIntPtr uIntPtr = (UIntPtr)(void*)Vector256&lt;long&gt;.Count; UIntPtr uIntPtr2 = (UIntPtr)(void*)((ulong)(UIntPtr)(void*)((ulong)length \/ (ulong)uIntPtr) \/ 2uL); for (UIntPtr uIntPtr3 = (UIntPtr)(void*)null; (ulong)uIntPtr3 &lt; (ulong)uIntPtr2; uIntPtr3 = (UIntPtr)(void*)((ulong)(long)(ulong)uIntPtr3 + 1uL)) { UIntPtr elementOffset = (UIntPtr)(void*)((ulong)(long)(ulong)uIntPtr3 * (ulong)(long)(ulong)uIntPtr); UIntPtr elementOffset2 = (UIntPtr)(void*)((ulong)(long)(ulong)length - (ulong)(long)(IntPtr)(void*)((long)(IntPtr)(void*)(1L + (long)(ulong)uIntPtr3) * (long)(ulong)uIntPtr)); Vector256&lt;long&gt; value = Vector256.LoadUnsafe(ref buf, elementOffset); Vector256&lt;long&gt; value2 = Vector256.LoadUnsafe(ref buf, elementOffset2); value = Avx2.Permute4x64(value, 27); value2 = Avx2.Permute4x64(value2, 27); value2.StoreUnsafe(ref buf, elementOffset); value.StoreUnsafe(ref buf, elementOffset2); } buf = ref Unsafe.Add(ref buf, (UIntPtr)(void*)((ulong)(long)(ulong)uIntPtr2 * (ulong)(long)(ulong)uIntPtr)); length = (UIntPtr)(void*)((ulong)(long)(ulong)length - (ulong)(long)(IntPtr)(void*)((long)(IntPtr)(void*)((long)(ulong)uIntPtr2 * (long)(ulong)uIntPtr) * 2L)); } else if (Vector128.IsHardwareAccelerated &amp;&amp; (ulong)(UIntPtr)(void*)((long)Vector128&lt;long&gt;.Count * 2L) &lt;= (ulong)length) { UIntPtr uIntPtr4 = (UIntPtr)(void*)Vector128&lt;long&gt;.Count; UIntPtr uIntPtr5 = (UIntPtr)(void*)((ulong)(UIntPtr)(void*)((ulong)length \/ (ulong)uIntPtr4) \/ 2uL); for (UIntPtr uIntPtr6 = (UIntPtr)(void*)null; (ulong)uIntPtr6 &lt; (ulong)uIntPtr5; uIntPtr6 = (UIntPtr)(void*)((ulong)(long)(ulong)uIntPtr6 + 1uL)) { UIntPtr elementOffset3 = (UIntPtr)(void*)((ulong)(long)(ulong)uIntPtr6 * (ulong)(long)(ulong)uIntPtr4); UIntPtr elementOffset4 = (UIntPtr)(void*)((ulong)(long)(ulong)length - (ulong)(long)(IntPtr)(void*)((long)(IntPtr)(void*)(1L + (long)(ulong)uIntPtr6) * (long)(ulong)uIntPtr4)); Vector128&lt;long&gt; vector = Vector128.LoadUnsafe(ref buf, elementOffset3); Vector128&lt;long&gt; vector2 = Vector128.LoadUnsafe(ref buf, elementOffset4); vector = Vector128.Shuffle(vector, Vector128.Create(1L, 0L)); vector2 = Vector128.Shuffle(vector2, Vector128.Create(1L, 0L)); vector2.StoreUnsafe(ref buf, elementOffset3); vector.StoreUnsafe(ref buf, elementOffset4); } buf = ref Unsafe.Add(ref buf, (UIntPtr)(void*)((ulong)(long)(ulong)uIntPtr5 * (ulong)(long)(ulong)uIntPtr4)); length = (UIntPtr)(void*)((ulong)(long)(ulong)length - (ulong)(long)(IntPtr)(void*)((long)(IntPtr)(void*)((long)(ulong)uIntPtr5 * (long)Vector128&lt;long&gt;.Count) * 2L)); }    ReverseInner(ref buf, length); }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0440\u0430\u0437\u043d\u043e\u043e\u0431\u0440\u0430\u0437\u0438\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443:<\/p>\n<pre><code class=\"cs\">    [Benchmark]     public int[] Array_Sort()     {         Array.Sort(array, 0, array.Length, _comparer);         return array;     }<\/code><\/pre>\n<pre><code class=\"cs\">public static void Sort&lt;[Nullable(2)] T&gt;(T[] array, int index, int length, [Nullable(new byte[] { 2, 1 })] IComparer&lt;T&gt; comparer) { if (array == null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array); } if (index &lt; 0) { ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException(); } if (length &lt; 0) { ThrowHelper.ThrowLengthArgumentOutOfRange_ArgumentOutOfRange_NeedNonNegNum(); } if (array.Length - index &lt; length) { ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen); } if (length &gt; 1) { Span&lt;T&gt; keys = new Span&lt;T&gt;(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(array), index), length); ArraySortHelper&lt;T&gt;.Default.Sort(keys, comparer); } }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u0446\u0438\u043a\u043b\u0430 for, \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u044b\u0439:<\/p>\n<pre><code class=\"cs\">    [Benchmark]     public int[] For()     {         for (int i = 0, length = array.Length - 1; i &lt; length \/ 2; i++)         {             int item = array[i];             array[i] = array[length - i];             array[length - i] = item;         }          return array;     }      [Benchmark]     public int[] For_Size()     {         for (int i = 0, length = array.Length - 1, size = length \/ 2; i &lt; size; i++)         {             int item = array[i];             array[i] = array[length - i];             array[length - i] = item;         }          return array;     }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043f\u0440\u0438\u0432\u0435\u0434\u0443 2 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430, \u043d\u043e \u0434\u0430\u043b\u0435\u0435 \u0432 \u043f\u043e\u043b\u043d\u043e\u043c \u043a\u043e\u0434\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u0441\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f. \u041e\u0442\u043c\u0435\u0447\u0443, \u0447\u0442\u043e \u0441\u0442\u043e\u043b\u044c \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u0441 \u0432\u0438\u0434\u0443 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f \u043f\u043e\u043c\u043e\u0433\u0430\u044e\u0442 \u0447\u0443\u0442\u044c \u0443\u0441\u043a\u043e\u0440\u0438\u0442\u0441\u044f, \u043d\u043e \u0442\u0443\u0442 \u043a\u0430\u0436\u0434\u044b\u0439 \u0441\u0430\u043c \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u043a\u0430\u043a \u0443\u0434\u043e\u0431\u043d\u0435\u0439 \u0434\u0435\u043b\u0430\u0442\u044c.<\/p>\n<p>\u0421\u0430\u0439\u0442 <a href=\"https:\/\/sharplab.io\" rel=\"noopener noreferrer nofollow\">https:\/\/sharplab.io<\/a> \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u043d\u0430 For():<\/p>\n<pre><code>using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions;  [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion(\"0.0.0.0\")] [module: UnverifiableCode] public class C {     private static int[] array;      public void M()     {         int i = 0;         for (int num = array.Length - 1; i &lt; num \/ 2; i++)         {             int num2 = array[i];             array[i] = array[num - i];             array[num - i] = num2;         }     }      static C()     {         int[] obj = new int[15];         RuntimeHelpers.InitializeArray(obj, (RuntimeFieldHandle)\/*OpCode not supported: LdMemberToken*\/);         array = obj;     } } [CompilerGenerated] internal sealed class &lt;PrivateImplementationDetails&gt; {     [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 60)]     private struct __StaticArrayInitTypeSize=60     {     }      internal static readonly __StaticArrayInitTypeSize=60 5A8B4F50AC386D79A3A5947122333429A35EBC81F89E807236ED66A4BB8FE498\/* Not supported: data(01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00 08 00 00 00 09 00 00 00 0A 00 00 00 0B 00 00 00 0C 00 00 00 0D 00 00 00 0E 00 00 00 0F 00 00 00) *\/; } <\/code><\/pre>\n<p>\u0412 \u0442\u043e \u0436\u0435 \u0432\u0440\u0435\u043c\u044f \u0434\u043b\u044f For_Size():<\/p>\n<pre><code>using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions;  [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion(\"0.0.0.0\")] [module: UnverifiableCode] public class C {     private static int[] array;      public void M()     {         int i = 0;         int num = array.Length - 1;         for (int num2 = num \/ 2; i &lt; num2; i++)         {             int num3 = array[i];             array[i] = array[num - i];             array[num - i] = num3;         }     }      static C()     {         int[] obj = new int[15];         RuntimeHelpers.InitializeArray(obj, (RuntimeFieldHandle)\/*OpCode not supported: LdMemberToken*\/);         array = obj;     } } [CompilerGenerated] internal sealed class &lt;PrivateImplementationDetails&gt; {     [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 60)]     private struct __StaticArrayInitTypeSize=60     {     }      internal static readonly __StaticArrayInitTypeSize=60 5A8B4F50AC386D79A3A5947122333429A35EBC81F89E807236ED66A4BB8FE498\/* Not supported: data(01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00 08 00 00 00 09 00 00 00 0A 00 00 00 0B 00 00 00 0C 00 00 00 0D 00 00 00 0E 00 00 00 0F 00 00 00) *\/; } <\/code><\/pre>\n<p>\u0418 \u0434\u043b\u044f \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u043b\u0435\u043d\u0438\u044f For_Unsafe_SameArray:<\/p>\n<pre><code class=\"cs\">using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions;  [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion(\"0.0.0.0\")] [module: UnverifiableCode] public class C {     private static int[] array;      public void M()     {         For_Unsafe_SameArray();     }      public unsafe int[] For_Unsafe_SameArray()     {         fixed (int* ptr = array)         {             int i = 0;             for (int num = array.Length - 1; i &lt; num \/ 2; i++)             {                 int num2 = ptr[i];                 ptr[i] = ptr[num - i];                 ptr[num - i] = num2;             }         }         return array;     }      static C()     {         int[] obj = new int[15];         RuntimeHelpers.InitializeArray(obj, (RuntimeFieldHandle)\/*OpCode not supported: LdMemberToken*\/);         array = obj;     } } [CompilerGenerated] internal sealed class &lt;PrivateImplementationDetails&gt; {     [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 60)]     private struct __StaticArrayInitTypeSize=60     {     }      internal static readonly __StaticArrayInitTypeSize=60 5A8B4F50AC386D79A3A5947122333429A35EBC81F89E807236ED66A4BB8FE498\/* Not supported: data(01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00 08 00 00 00 09 00 00 00 0A 00 00 00 0B 00 00 00 0C 00 00 00 0D 00 00 00 0E 00 00 00 0F 00 00 00) *\/; }<\/code><\/pre>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432 \u0438\u0442\u043e\u0433\u043e\u0432\u043e\u043c \u043b\u0438\u0441\u0442\u0438\u043d\u0433\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 unsafe \u0438 range \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u0432\u0430\u0440\u0438\u0430\u0446\u0438\u044f\u0445.<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cs\">using BenchmarkDotNet.Attributes;  namespace Benchmarks.Benchmarks.Arrays;  [MemoryDiagnoser] public class ArrayReverseSameArray {     private static readonly Comparer&lt;int&gt; _comparer = Comparer&lt;int&gt;.Create((x, y) =&gt; y.CompareTo(x));      [Params(1000, 10_000, 100_000, 1_000_000, 100_000_000)]     public int NumberCount;      private int[] array;      [GlobalSetup]     public void GlobalSetup()     {         array = Enumerable.Range(1, NumberCount).ToArray();     }      [Benchmark]     public int[] While()     {         if (array.Length == 0)         {             return Array.Empty&lt;int&gt;();         }          int i = -1;         int j = array.Length;          while (i++ &lt; j--)         {             int temp = array[i];             array[i] = array[j];             array[j] = temp;         }          return array;     }      [Benchmark]     public int[] Array_Reverse()     {         Array.Reverse(array);         return array;     }      [Benchmark]     public int[] Array_Sort()     {         Array.Sort(array, 0, array.Length, _comparer);         return array;     }      [Benchmark]     public int[] For()     {         for (int i = 0, length = array.Length - 1; i &lt; length \/ 2; i++)         {             int item = array[i];             array[i] = array[length - i];             array[length - i] = item;         }          return array;     }      [Benchmark]     public int[] For_Size()     {         for (int i = 0, length = array.Length - 1, size = length \/ 2; i &lt; size; i++)         {             int item = array[i];             array[i] = array[length - i];             array[length - i] = item;         }          return array;     }      [Benchmark]     public unsafe int[] For_Unsafe()     {         fixed (int* arrayItem = array)         {             for (int i = 0, length = array.Length - 1; i &lt; length \/ 2; i++)             {                 int item = arrayItem[i];                 arrayItem[i] = arrayItem[length - i];                 arrayItem[length - i] = item;             }         }          return array;     }      [Benchmark]     public unsafe int[] For_Unsafe_Size()     {         fixed (int* arrayItem = array)         {             for (int i = 0, length = array.Length - 1, size = length \/ 2; i &lt; size; i++)             {                 int item = arrayItem[i];                 arrayItem[i] = arrayItem[length - i];                 arrayItem[length - i] = item;             }         }          return array;     }      [Benchmark]     public int[] For_Range()     {         for (int i = 0, length = array.Length - 1; i &lt; length \/ 2; i++)         {             (array[^(i + 1)], array[i]) = (array[i], array[^(i + 1)]);         }          return array;     }      [Benchmark]     public int[] For_Range_Size()     {         for (int i = 0, length = array.Length - 1, size = length \/ 2; i &lt; size; i++)         {             (array[^(i + 1)], array[i]) = (array[i], array[^(i + 1)]);         }          return array;     }      [Benchmark]     public int[] For_Range_v2()     {         for (int i = 0, length = array.Length - 1; i &lt; length \/ 2; i++)         {             (array[i], array[length - i]) = (array[length - i], array[i]);         }          return array;     }      [Benchmark]     public int[] For_Range_v2_Size()     {         for (int i = 0, length = array.Length - 1, size = length \/ 2; i &lt; size; i++)         {             (array[i], array[length - i]) = (array[length - i], array[i]);         }          return array;     }      [Benchmark]     public unsafe int[] For_Range_v2_Unsafe()     {         fixed (int* arrayItem = array)         {             for (int i = 0, length = array.Length - 1; i &lt; length \/ 2; i++)             {                 (arrayItem[i], arrayItem[length - i]) = (arrayItem[length - i], arrayItem[i]);             }         }          return array;     }      [Benchmark]     public unsafe int[] For_Range_v2_Unsafe_Size()     {         fixed (int* arrayItem = array)         {             for (int i = 0, length = array.Length - 1, size = length \/ 2; i &lt; size; i++)             {                 (arrayItem[i], arrayItem[length - i]) = (arrayItem[length - i], arrayItem[i]);             }         }          return array;     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/4ae\/335\/c52\/4ae335c52d9d4d2b95daf90e34606741.jpg\" alt=\"Array_Reverse \u0445\u043e\u0440\u043e\u0448\" title=\"Array_Reverse \u0445\u043e\u0440\u043e\u0448\" width=\"920\" height=\"1086\"><\/p>\n<div><figcaption>Array_Reverse \u0445\u043e\u0440\u043e\u0448<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0447\u0442\u043e \u043d\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u0445 \u0432\u0435\u0437\u0434\u0435 \u0431\u0443\u0434\u0435\u0442, \u043f\u0443\u0441\u0442\u044c \u0438 \u043d\u0435\u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439, \u043d\u043e \u0440\u0430\u0441\u0445\u043e\u0434 \u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<p>\u041f\u0440\u0438\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u043d\u044b. \u0420\u0435\u0447\u044c \u043f\u0440\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0442 \u043d\u043e\u0432\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432\u0445\u043e\u0434\u043d\u043e\u0433\u043e.<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cs\">using BenchmarkDotNet.Attributes;  namespace Benchmarks.Benchmarks.Arrays;  [MemoryDiagnoser] public class ArrayReverseNewArray {     private static readonly Comparer&lt;int&gt; _comparer = Comparer&lt;int&gt;.Create((x, y) =&gt; y.CompareTo(x));      [Params(1000, 10_000, 100_000, 1_000_000, 100_000_000)]     public int NumberCount;          private int[] array;      [GlobalSetup]     public void GlobalSetup()     {         array = Enumerable.Range(1, NumberCount).ToArray();     }      [Benchmark]     public int[] Array_Reverse_ToArray()     {         int[] items = array.ToArray();          Array.Reverse(items);         return items;     }          [Benchmark]     public int[] Array_Reverse_CopyTo()     {         int[] results = new int[array.Length];         array.CopyTo(results, 0);          Array.Reverse(results);         return results;     }      [Benchmark]     public int[] For()     {         int[] items = new int[array.Length];          int j = 0;         for (int i = array.Length - 1; i &gt; -1; i--)         {             items[j++] = array[i];         }          return items;     }      [Benchmark]     public int[] Enumerable_ToArray()     {         return array.Reverse().ToArray();     }      [Benchmark]     public int[] Stack_ToArray()     {         Stack&lt;int&gt; stack = new(array);         return stack.ToArray();     }      [Benchmark]     public int[] Stack_CopyTo()     {         Stack&lt;int&gt; stack = new(array);          int[] results = new int[stack.Count];         stack.CopyTo(results, 0);          return results;     }      [Benchmark]     public int[] OrderByDescending_ToArray()     {         return array.OrderByDescending(x =&gt; x).ToArray();     }      [Benchmark]     public int[] QueryOperators_OrderByDescending_ToArray()     {         return (from x in array orderby x descending select x).ToArray();     }      [Benchmark]     public int[] List_ToArray()     {         List&lt;int&gt; items = new(array);         items.Reverse();          return items.ToArray();     }      [Benchmark]     public int[] List_CopyTo()     {         List&lt;int&gt; items = new(array);         items.Reverse();          int[] results = new int[items.Count];         items.CopyTo(results, 0);          return results;     }      [Benchmark]     public int[] List_Sort()     {         List&lt;int&gt; items = new(array);         items.Sort(_comparer);          return items.ToArray();     }      [Benchmark]     public int[] List_Sort_CopyTo()     {         List&lt;int&gt; items = new(array);         items.Sort(_comparer);          int[] results = new int[items.Count];         items.CopyTo(results, 0);          return results;     }      [Benchmark]     public int[] Span_ToArray()     {         Span&lt;int&gt; items = new(array);         items.Reverse();          return items.ToArray();     }      [Benchmark]     public int[] Span_Sort_ToArray()     {         Span&lt;int&gt; items = new(array);         items.Sort(_comparer);          return items.ToArray();     }      [Benchmark]     public int[] SortedSet_ToArray()     {         SortedSet&lt;int&gt; items = new(array, _comparer);         return items.ToArray();     }      [Benchmark]     public int[] SortedSet_CopyTo()     {         SortedSet&lt;int&gt; items = new(array, _comparer);          int[] results = new int[items.Count];         items.CopyTo(results, 0);          return results;     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0418\u0442\u043e\u0433 80-\u0442\u0438 \u0442\u0435\u0441\u0442\u043e\u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/4e1\/647\/b94\/4e1647b9453f28804182743247053871.jpg\" alt=\"Span_ToArray \u0445\u043e\u0440\u043e\u0448\" title=\"Span_ToArray \u0445\u043e\u0440\u043e\u0448\" width=\"1587\" height=\"1323\"><\/p>\n<div><figcaption>Span_ToArray \u0445\u043e\u0440\u043e\u0448<\/figcaption><\/div>\n<\/figure>\n<p>\u0414\u043b\u044f \u043e\u0431\u0449\u0435\u0433\u043e \u0438\u0442\u043e\u0433\u0430, \u0445\u043e\u0442\u044c \u0432\u044b\u0432\u043e\u0434\u044b \u0443\u0436\u0435 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u044b, \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043b\u0443\u0447\u0448\u0438\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u0438\u0437 \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u0432:<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cs\">using BenchmarkDotNet.Attributes;  namespace Benchmarks.Benchmarks.Arrays;  [MemoryDiagnoser] public class ArrayReverseFaster {     [Params(1000, 10_000, 100_000, 1_000_000, 100_000_000, 1_000_000_000)]     public int NumberCount;      private int[] array;      [GlobalSetup]     public void GlobalSetup()     {         array = Enumerable.Range(1, NumberCount).ToArray();     }      [Benchmark]     public int[] Array_Reverse_SameArray()     {         Array.Reverse(array);         return array;     }      [Benchmark]     public unsafe int[] For_Unsafe_SameArray()     {         fixed (int* arrayItem = array)         {             for (int i = 0, length = array.Length - 1; i &lt; length \/ 2; i++)             {                 int item = arrayItem[i];                 arrayItem[i] = arrayItem[length - i];                 arrayItem[length - i] = item;             }         }          return array;     }      [Benchmark]     public unsafe int[] For_Unsafe_SameArray_Length()     {         int length = array.Length - 1;         fixed (int* arrayItem = array)         {             for (int i = 0; i &lt; length \/ 2; i++)             {                 int item = arrayItem[i];                 arrayItem[i] = arrayItem[length - i];                 arrayItem[length - i] = item;             }         }          return array;     }      [Benchmark]     public unsafe int[] For_Unsafe_SameArray_Size()     {         int length = array.Length - 1;         int size = length \/ 2;          fixed (int* arrayItem = array)         {             for (int i = 0; i &lt; size; i++)             {                 int item = arrayItem[i];                 arrayItem[i] = arrayItem[length - i];                 arrayItem[length - i] = item;             }         }          return array;     }      [Benchmark]     public int[] Array_Reverse_ToArray()     {         int[] items = array.ToArray();          Array.Reverse(items);         return items;     }      [Benchmark]     public int[] Array_Reverse_CopyTo()     {         int[] results = new int[array.Length];         array.CopyTo(results, 0);          Array.Reverse(results);         return results;     }      [Benchmark]     public int[] Enumerable_ToArray()     {         return array.Reverse().ToArray();     }      [Benchmark]     public int[] Span_ToArray()     {         Span&lt;int&gt; items = new(array);         items.Reverse();          return items.ToArray();     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0418\u0442\u043e\u0433 \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u0441\u0430\u043c \u0437\u0430 \u0441\u0435\u0431\u044f:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/88a\/80c\/91f\/88a80c91f4d5e35af90683af633a655b.jpg\" width=\"1424\" height=\"814\"><\/figure>\n<p>\u0418 \u043d\u0430 \u0437\u0430\u043a\u0443\u0441\u043a\u0443 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0441 <a href=\"https:\/\/referencesource.microsoft.com\" rel=\"noopener noreferrer nofollow\">https:\/\/referencesource.microsoft.com<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043d\u043e\u0433\u0434\u0430 \u0440\u0430\u0434\u0443\u0435\u0442 \u0438 \u0443\u0434\u0438\u0432\u043b\u044f\u0435\u0442 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e.<\/p>\n<p>Stack.<a href=\"https:\/\/referencesource.microsoft.com\/mscorlib\/R\/257d8a090a3bf13a.html\" rel=\"noopener noreferrer nofollow\">ToArray<\/a>() (namespace System.Collections):<\/p>\n<pre><code class=\"cs\">\/\/ Copies the Stack to an array, in the same order Pop would return the items.     public virtual Object[] ToArray()     {         Contract.Ensures(Contract.Result&lt;Object[]&gt;() != null);          Object[] objArray = new Object[_size];         int i = 0;         while (i &lt; _size)         {             objArray[i] = _array[_size - i - 1];             i++;         }         return objArray;     }<\/code><\/pre>\n<p>List.<a href=\"https:\/\/referencesource.microsoft.com\/mscorlib\/R\/257d8a090a3bf13a.html\" rel=\"noopener noreferrer nofollow\">ToArray<\/a>() (namespace System.Collections.Generic):<\/p>\n<pre><code class=\"cs\">    \/\/ ToArray returns a new Object array containing the contents of the List.     \/\/ This requires copying the List, which is an O(n) operation.     public T[] ToArray()     {         Contract.Ensures(Contract.Result&lt;T[]&gt;() != null);         Contract.Ensures(Contract.Result&lt;T[]&gt;().Length == Count);          T[] array = new T[_size];         Array.Copy(_items, 0, array, 0, _size);         return array;     }<\/code><\/pre>\n<p>\u0412\u0441\u0435\u043c \u0443\u0434\u0430\u0447\u0438 \u0438 \u0434\u043e \u043d\u043e\u0432\u044b\u0445 \u0432\u0441\u0442\u0440\u0435\u0447!<\/p>\n<p>P.S.: \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0435 \u0442\u0435\u0441\u0442\u044b \u043a\u0440\u0430\u0439\u043d\u0435 \u0434\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 (20 &#8212; 90+ \u043c\u0438\u043d\u0443\u0442 \u043d\u0430 1 \u0442\u0435\u0441\u0442) \u0438 \u0435\u0441\u043b\u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0442\u044c, \u043b\u0443\u0447\u0448\u0435 \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u044c \u0432\u044b\u0431\u043e\u0440\u043a\u0443.<\/p>\n<\/div>\n<\/div>\n<p> <!----> <!----><\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/739674\/\"> https:\/\/habr.com\/ru\/articles\/739674\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<p>\u0423\u0432\u0430\u0436\u0430\u0435\u043c\u044b\u0435 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0438, \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u0442\u0435\u0441\u0442\u0430\u0445 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0441\u0432\u043e\u0438 \u0432\u044b\u0432\u043e\u0434\u044b. \u0422\u0435\u0441\u0442\u044b \u0441\u0434\u0435\u043b\u0430\u043d\u044b \u043d\u0430 .net 7.<\/p>\n<p>\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043b \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c BenchmarkDotNet, \u0442\u0430\u043a \u0447\u0442\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u0432\u044b\u0432\u043e\u0434\u044b.<\/p>\n<p>\u0421\u0440\u0430\u0437\u0443 \u043e\u0442\u043c\u0435\u0447\u0443, \u0447\u0442\u043e \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0430\u0442\u0440\u0438\u0431\u0443\u0442 [GlobalSetup], \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0435 \u043f\u0435\u0440\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u043e \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u00abExecuted once per each N value\u00bb \u0438 \u044d\u0442\u043e \u043d\u0430\u043c \u0438 \u043d\u0430\u0434\u043e.<\/p>\n<p>\u0414\u043b\u044f \u043f\u043e\u043b\u043d\u043e\u0439 \u043a\u0430\u0440\u0442\u0438\u043d\u044b \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0442\u0435\u0441\u0442\u044b \u0438\u0434\u0443\u0442 \u043d\u0430 \u043c\u0430\u0441\u0441\u0438\u0432\u0430\u0445 \u0441 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 1000, 10_000, 100_000, 1_000_000, 100_000_000, \u0430 \u0441\u0430\u043c\u044b\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0441 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u0434\u043e 1_000_000_000 \u0447\u0438\u0441\u0435\u043b.<\/p>\n<p>\u041f\u0435\u0440\u0432\u044b\u0435 \u0442\u0435\u0441\u0442\u044b \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u0441 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0431\u0435\u0437 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e, \u0447\u0442\u043e \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u0435\u0440\u043d\u044b\u0439 \u0432\u044b\u0431\u043e\u0440, \u043d\u043e \u043f\u0430\u043c\u044f\u0442\u0438 \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 (\u0442\u0435\u0441\u0442\u044b \u043f\u043e\u043a\u0430\u0436\u0443\u0442 \u0441\u0442\u0440\u0430\u043d\u043d\u043e\u0441\u0442\u044c \u043d\u0430 \u043a\u0440\u0443\u043f\u043d\u043e\u0439 \u0432\u044b\u0431\u043e\u0440\u043a\u0435).<\/p>\n<p>\u0414\u043b\u044f \u0441\u0442\u0430\u0440\u0442\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0431\u044b\u0447\u043d\u044b\u0439 While, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u0432 \u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438, \u0447\u0435\u043c \u0430\u043d\u0430\u043b\u043e\u0433\u0438 \u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u043e\u0440\u0430\u0445 \u0441\u0435\u0442\u0438:<\/p>\n<pre><code class=\"cs\">    [Benchmark]     public int[] While()     {         if (array.Length == 0)         {             return Array.Empty&lt;int&gt;();         }          int i = -1;         int j = array.Length;          while (i++ &lt; j--)         {             int temp = array[i];             array[i] = array[j];             array[j] = temp;         }          return array;     }<\/code><\/pre>\n<p>\u0421\u0430\u043c\u044b\u0439 \u0447\u0430\u0441\u0442\u043e \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u0435\u043c\u044b\u0439 \u043e\u0442\u0432\u0435\u0442 \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441:<\/p>\n<pre><code class=\"cs\">    [Benchmark]     public int[] Array_Reverse()     {         Array.Reverse(array);         return array;     }<\/code><\/pre>\n<p>\u041d\u0435 \u0441\u043a\u0430\u0436\u0443, \u0447\u0442\u043e \u0442\u0443\u0442 \u0432\u0441\u0435 \u043f\u043b\u043e\u0445\u043e, \u0432\u0435\u0434\u044c \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c \u0442\u0430\u043c \u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0431\u043e\u0442\u044b \u0441 unsafe \u0438 \u0440\u0430\u0437\u043d\u043e\u0439 \u00ab\u043c\u0430\u0433\u0438\u0438\u00bb \u0434\u043b\u044f \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"cs\">public unsafe static void Reverse&lt;[Nullable(2)] T&gt;(T[] array) { if (array == null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array); } if (array.Length &gt; 1) { SpanHelpers.Reverse(ref MemoryMarshal.GetArrayDataReference(array), (UIntPtr)(void*)array.Length); } }  [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Reverse&lt;T&gt;(ref T elements, UIntPtr length) { if (!RuntimeHelpers.IsReferenceOrContainsReferences&lt;T&gt;()) { if (Unsafe.SizeOf&lt;T&gt;() == 1) { Reverse(ref Unsafe.As&lt;T, byte&gt;(ref elements), length); return; } if (Unsafe.SizeOf&lt;T&gt;() == 2) { Reverse(ref Unsafe.As&lt;T, char&gt;(ref elements), length); return; } if (Unsafe.SizeOf&lt;T&gt;() == 4) { Reverse(ref Unsafe.As&lt;T, int&gt;(ref elements), length); return; } if (Unsafe.SizeOf&lt;T&gt;() == 8) { Reverse(ref Unsafe.As&lt;T, long&gt;(ref elements), length); return; } } ReverseInner(ref elements, length); }  public unsafe static void Reverse(ref long buf, UIntPtr length) { if (Avx2.IsSupported &amp;&amp; (ulong)(UIntPtr)(void*)((long)Vector256&lt;long&gt;.Count * 2L) &lt;= (ulong)length) { UIntPtr uIntPtr = (UIntPtr)(void*)Vector256&lt;long&gt;.Count; UIntPtr uIntPtr2 = (UIntPtr)(void*)((ulong)(UIntPtr)(void*)((ulong)length \/ (ulong)uIntPtr) \/ 2uL); for (UIntPtr uIntPtr3 = (UIntPtr)(void*)null; (ulong)uIntPtr3 &lt; (ulong)uIntPtr2; uIntPtr3 = (UIntPtr)(void*)((ulong)(long)(ulong)uIntPtr3 + 1uL)) { UIntPtr elementOffset = (UIntPtr)(void*)((ulong)(long)(ulong)uIntPtr3 * (ulong)(long)(ulong)uIntPtr); UIntPtr elementOffset2 = (UIntPtr)(void*)((ulong)(long)(ulong)length - (ulong)(long)(IntPtr)(void*)((long)(IntPtr)(void*)(1L + (long)(ulong)uIntPtr3) * (long)(ulong)uIntPtr)); Vector256&lt;long&gt; value = Vector256.LoadUnsafe(ref buf, elementOffset); Vector256&lt;long&gt; value2 = Vector256.LoadUnsafe(ref buf, elementOffset2); value = Avx2.Permute4x64(value, 27); value2 = Avx2.Permute4x64(value2, 27); value2.StoreUnsafe(ref buf, elementOffset); value.StoreUnsafe(ref buf, elementOffset2); } buf = ref Unsafe.Add(ref buf, (UIntPtr)(void*)((ulong)(long)(ulong)uIntPtr2 * (ulong)(long)(ulong)uIntPtr)); length = (UIntPtr)(void*)((ulong)(long)(ulong)length - (ulong)(long)(IntPtr)(void*)((long)(IntPtr)(void*)((long)(ulong)uIntPtr2 * (long)(ulong)uIntPtr) * 2L)); } else if (Vector128.IsHardwareAccelerated &amp;&amp; (ulong)(UIntPtr)(void*)((long)Vector128&lt;long&gt;.Count * 2L) &lt;= (ulong)length) { UIntPtr uIntPtr4 = (UIntPtr)(void*)Vector128&lt;long&gt;.Count; UIntPtr uIntPtr5 = (UIntPtr)(void*)((ulong)(UIntPtr)(void*)((ulong)length \/ (ulong)uIntPtr4) \/ 2uL); for (UIntPtr uIntPtr6 = (UIntPtr)(void*)null; (ulong)uIntPtr6 &lt; (ulong)uIntPtr5; uIntPtr6 = (UIntPtr)(void*)((ulong)(long)(ulong)uIntPtr6 + 1uL)) { UIntPtr elementOffset3 = (UIntPtr)(void*)((ulong)(long)(ulong)uIntPtr6 * (ulong)(long)(ulong)uIntPtr4); UIntPtr elementOffset4 = (UIntPtr)(void*)((ulong)(long)(ulong)length - (ulong)(long)(IntPtr)(void*)((long)(IntPtr)(void*)(1L + (long)(ulong)uIntPtr6) * (long)(ulong)uIntPtr4)); Vector128&lt;long&gt; vector = Vector128.LoadUnsafe(ref buf, elementOffset3); Vector128&lt;long&gt; vector2 = Vector128.LoadUnsafe(ref buf, elementOffset4); vector = Vector128.Shuffle(vector, Vector128.Create(1L, 0L)); vector2 = Vector128.Shuffle(vector2, Vector128.Create(1L, 0L)); vector2.StoreUnsafe(ref buf, elementOffset3); vector.StoreUnsafe(ref buf, elementOffset4); } buf = ref Unsafe.Add(ref buf, (UIntPtr)(void*)((ulong)(long)(ulong)uIntPtr5 * (ulong)(long)(ulong)uIntPtr4)); length = (UIntPtr)(void*)((ulong)(long)(ulong)length - (ulong)(long)(IntPtr)(void*)((long)(IntPtr)(void*)((long)(ulong)uIntPtr5 * (long)Vector128&lt;long&gt;.Count) * 2L)); }    ReverseInner(ref buf, length); }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0440\u0430\u0437\u043d\u043e\u043e\u0431\u0440\u0430\u0437\u0438\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443:<\/p>\n<pre><code class=\"cs\">    [Benchmark]     public int[] Array_Sort()     {         Array.Sort(array, 0, array.Length, _comparer);         return array;     }<\/code><\/pre>\n<pre><code class=\"cs\">public static void Sort&lt;[Nullable(2)] T&gt;(T[] array, int index, int length, [Nullable(new byte[] { 2, 1 })] IComparer&lt;T&gt; comparer) { if (array == null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array); } if (index &lt; 0) { ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException(); } if (length &lt; 0) { ThrowHelper.ThrowLengthArgumentOutOfRange_ArgumentOutOfRange_NeedNonNegNum(); } if (array.Length - index &lt; length) { ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen); } if (length &gt; 1) { Span&lt;T&gt; keys = new Span&lt;T&gt;(ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(array), index), length); ArraySortHelper&lt;T&gt;.Default.Sort(keys, comparer); } }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u0446\u0438\u043a\u043b\u0430 for, \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u044b\u0439:<\/p>\n<pre><code class=\"cs\">    [Benchmark]     public int[] For()     {         for (int i = 0, length = array.Length - 1; i &lt; length \/ 2; i++)         {             int item = array[i];             array[i] = array[length - i];             array[length - i] = item;         }          return array;     }      [Benchmark]     public int[] For_Size()     {         for (int i = 0, length = array.Length - 1, size = length \/ 2; i &lt; size; i++)         {             int item = array[i];             array[i] = array[length - i];             array[length - i] = item;         }          return array;     }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043f\u0440\u0438\u0432\u0435\u0434\u0443 2 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430, \u043d\u043e \u0434\u0430\u043b\u0435\u0435 \u0432 \u043f\u043e\u043b\u043d\u043e\u043c \u043a\u043e\u0434\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u0441\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f. \u041e\u0442\u043c\u0435\u0447\u0443, \u0447\u0442\u043e \u0441\u0442\u043e\u043b\u044c \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u0441 \u0432\u0438\u0434\u0443 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f \u043f\u043e\u043c\u043e\u0433\u0430\u044e\u0442 \u0447\u0443\u0442\u044c \u0443\u0441\u043a\u043e\u0440\u0438\u0442\u0441\u044f, \u043d\u043e \u0442\u0443\u0442 \u043a\u0430\u0436\u0434\u044b\u0439 \u0441\u0430\u043c \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u043a\u0430\u043a \u0443\u0434\u043e\u0431\u043d\u0435\u0439 \u0434\u0435\u043b\u0430\u0442\u044c.<\/p>\n<p>\u0421\u0430\u0439\u0442 <a href=\"https:\/\/sharplab.io\" rel=\"noopener noreferrer nofollow\">https:\/\/sharplab.io<\/a> \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u043d\u0430 For():<\/p>\n<pre><code>using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions;  [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion(\"0.0.0.0\")] [module: UnverifiableCode] public class C {     private static int[] array;      public void M()     {         int i = 0;         for (int num = array.Length - 1; i &lt; num \/ 2; i++)         {             int num2 = array[i];             array[i] = array[num - i];             array[num - i] = num2;         }     }      static C()     {         int[] obj = new int[15];         RuntimeHelpers.InitializeArray(obj, (RuntimeFieldHandle)\/*OpCode not supported: LdMemberToken*\/);         array = obj;     } } [CompilerGenerated] internal sealed class &lt;PrivateImplementationDetails&gt; {     [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 60)]     private struct __StaticArrayInitTypeSize=60     {     }      internal static readonly __StaticArrayInitTypeSize=60 5A8B4F50AC386D79A3A5947122333429A35EBC81F89E807236ED66A4BB8FE498\/* Not supported: data(01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00 08 00 00 00 09 00 00 00 0A 00 00 00 0B 00 00 00 0C 00 00 00 0D 00 00 00 0E 00 00 00 0F 00 00 00) *\/; } <\/code><\/pre>\n<p>\u0412 \u0442\u043e \u0436\u0435 \u0432\u0440\u0435\u043c\u044f \u0434\u043b\u044f For_Size():<\/p>\n<pre><code>using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions;  [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion(\"0.0.0.0\")] [module: UnverifiableCode] public class C {     private static int[] array;      public void M()     {         int i = 0;         int num = array.Length - 1;         for (int num2 = num \/ 2; i &lt; num2; i++)         {             int num3 = array[i];             array[i] = array[num - i];             array[num - i] = num3;         }     }      static C()     {         int[] obj = new int[15];         RuntimeHelpers.InitializeArray(obj, (RuntimeFieldHandle)\/*OpCode not supported: LdMemberToken*\/);         array = obj;     } } [CompilerGenerated] internal sealed class &lt;PrivateImplementationDetails&gt; {     [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 60)]     private struct __StaticArrayInitTypeSize=60     {     }      internal static readonly __StaticArrayInitTypeSize=60 5A8B4F50AC386D79A3A5947122333429A35EBC81F89E807236ED66A4BB8FE498\/* Not supported: data(01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00 08 00 00 00 <\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-348353","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/348353","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=348353"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/348353\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=348353"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=348353"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=348353"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}