DragonECS/src/Internal/ArraySortHalperX.cs

273 lines
8.6 KiB
C#
Raw Normal View History

2025-03-14 16:53:25 +08:00
#if DISABLE_DEBUG
#undef DEBUG
#endif
using System;
2024-08-26 11:08:13 +08:00
using System.Collections.Generic;
2024-01-07 18:52:54 +08:00
using System.Runtime.CompilerServices;
2024-08-31 14:57:42 +08:00
#if ENABLE_IL2CPP
using Unity.IL2CPP.CompilerServices;
#endif
2024-01-07 18:52:54 +08:00
namespace DCFApixels.DragonECS.Internal
{
2024-08-26 11:08:13 +08:00
internal interface IStructComparer<T> : IComparer<T>
2024-01-07 18:52:54 +08:00
{
// a > b = return > 0
2024-08-26 11:08:13 +08:00
// int Compare(T a, T b);
2024-01-07 18:52:54 +08:00
}
2024-08-26 11:08:13 +08:00
2024-08-31 14:57:42 +08:00
#if ENABLE_IL2CPP
2024-11-08 17:21:36 +08:00
[Il2CppSetOption(Option.NullChecks, false)]
2024-08-31 14:57:42 +08:00
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
#endif
2024-01-07 18:52:54 +08:00
internal static class ArraySortHalperX<T>
{
private const int IntrosortSizeThreshold = 16;
2024-08-26 11:08:13 +08:00
#region IStructComparer
2024-01-07 18:52:54 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-08-23 22:31:43 +08:00
public static void SwapIfGreater<TComparer>(T[] items, ref TComparer comparer, int i, int j) where TComparer : IStructComparer<T>
2024-01-07 18:52:54 +08:00
{
if (comparer.Compare(items[i], items[j]) > 0)
{
T key = items[i];
items[i] = items[j];
items[j] = key;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-08-23 22:31:43 +08:00
public static void InsertionSort<TComparer>(T[] items, ref TComparer comparer) where TComparer : IStructComparer<T>
2024-01-07 18:52:54 +08:00
{
for (int i = 0; i < items.Length - 1; i++)
{
T t = items[i + 1];
int j = i;
while (j >= 0 && comparer.Compare(t, items[j]) < 0)
{
items[j + 1] = items[j];
j--;
}
items[j + 1] = t;
}
}
2024-08-26 11:08:13 +08:00
2024-01-07 18:52:54 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-08-23 22:31:43 +08:00
public static void Sort<TComparer>(T[] items, ref TComparer comparer) where TComparer : IStructComparer<T>
2024-01-07 18:52:54 +08:00
{
int length = items.Length;
if (length == 1)
{
return;
}
if (length <= IntrosortSizeThreshold)
{
if (length == 2)
{
SwapIfGreater(items, ref comparer, 0, 1);
return;
}
if (length == 3)
{
SwapIfGreater(items, ref comparer, 0, 1);
SwapIfGreater(items, ref comparer, 0, 2);
SwapIfGreater(items, ref comparer, 1, 2);
return;
}
InsertionSort(items, ref comparer);
return;
}
2024-08-26 11:08:13 +08:00
2024-08-23 22:31:43 +08:00
IStructComparer<T> packed = comparer;
2024-08-26 11:08:13 +08:00
Array.Sort(items, 0, items.Length, packed);
2024-01-07 18:52:54 +08:00
comparer = (TComparer)packed;
}
2024-08-26 11:08:13 +08:00
#endregion
#region Comparison
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void SwapIfGreater(T[] items, Comparison<T> comparison, int i, int j)
{
if (comparison(items[i], items[j]) > 0)
{
T key = items[i];
items[i] = items[j];
items[j] = key;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void InsertionSort(T[] items, int length, Comparison<T> comparison)
{
for (int i = 0; i < length - 1; i++)
{
T t = items[i + 1];
int j = i;
while (j >= 0 && comparison(t, items[j]) < 0)
{
items[j + 1] = items[j];
j--;
}
items[j + 1] = t;
}
}
2024-08-31 14:57:42 +08:00
#if ENABLE_IL2CPP
2024-11-08 17:21:36 +08:00
[Il2CppSetOption(Option.NullChecks, false)]
2024-08-31 14:57:42 +08:00
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
#endif
2024-08-26 11:08:13 +08:00
private class ComparisonHach : IComparer<T>
{
public static readonly ComparisonHach Instance = new ComparisonHach();
public Comparison<T> comparison;
private ComparisonHach() { }
public int Compare(T x, T y) { return comparison(x, y); }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Sort(T[] items, Comparison<T> comparison)
{
Sort(items, comparison, items.Length);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Sort(T[] items, Comparison<T> comparison, int length)
{
if (length <= IntrosortSizeThreshold)
{
if (length == 1)
{
return;
}
if (length == 2)
{
SwapIfGreater(items, comparison, 0, 1);
return;
}
if (length == 3)
{
SwapIfGreater(items, comparison, 0, 1);
SwapIfGreater(items, comparison, 0, 2);
SwapIfGreater(items, comparison, 1, 2);
return;
}
InsertionSort(items, length, comparison);
return;
}
ComparisonHach.Instance.comparison = comparison;
Array.Sort(items, 0, length, ComparisonHach.Instance);
}
#endregion
2024-01-07 18:52:54 +08:00
}
2024-08-31 14:57:42 +08:00
#if ENABLE_IL2CPP
2024-11-08 17:21:36 +08:00
[Il2CppSetOption(Option.NullChecks, false)]
2024-08-31 14:57:42 +08:00
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
#endif
2024-01-07 18:52:54 +08:00
internal static unsafe class UnsafeArraySortHalperX<T> where T : unmanaged
{
private const int IntrosortSizeThreshold = 16;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-08-23 22:31:43 +08:00
public static void SwapIfGreater<TComparer>(T* items, ref TComparer comparer, int i, int j) where TComparer : IStructComparer<T>
2024-01-07 18:52:54 +08:00
{
if (comparer.Compare(items[i], items[j]) > 0)
{
T key = items[i];
items[i] = items[j];
items[j] = key;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-08-23 22:31:43 +08:00
public static void InsertionSort_Unchecked<TComparer>(T* items, int length, ref TComparer comparer) where TComparer : IStructComparer<T>
2024-01-07 18:52:54 +08:00
{
for (int i = 0; i < length - 1; i++)
{
T t = items[i + 1];
int j = i;
while (j >= 0 && comparer.Compare(t, items[j]) < 0)
{
items[j + 1] = items[j];
j--;
}
items[j + 1] = t;
}
}
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
//public static void OptimizedBubbleSort_Unchecked<TComparer>(T* items, int length, ref TComparer comparer) where TComparer : IComparerX<T>
//{
// for (int i = 0, n = length - 1; i < n; i++)
// {
// bool noSwaped = true;
// for (int j = 0; j < n - i;)
// {
// ref T j0 = ref items[j++];
// if(comparer.Compare(j0, items[j]) < 0)
// {
// T tmp = items[j];
// items[j] = j0;
// j0 = tmp;
// noSwaped = false;
// }
// }
// if (noSwaped)
// break;
// }
//}
2024-08-23 22:31:43 +08:00
public static void InsertionSort<TComparer>(T* items, int length, ref TComparer comparer) where TComparer : IStructComparer<T>
2024-01-07 18:52:54 +08:00
{
if (length == 1)
{
return;
}
if (length == 2)
{
SwapIfGreater(items, ref comparer, 0, 1);
return;
}
if (length == 3)
{
SwapIfGreater(items, ref comparer, 0, 1);
SwapIfGreater(items, ref comparer, 0, 2);
SwapIfGreater(items, ref comparer, 1, 2);
return;
}
InsertionSort_Unchecked(items, length, ref comparer);
}
//public static void OptimizedBubbleSort<TComparer>(T* items, int length, ref TComparer comparer) where TComparer : IComparerX<T>
//{
// if (length == 1)
// {
// return;
// }
//
// if (length == 2)
// {
// SwapIfGreater(items, ref comparer, 0, 1);
// return;
// }
//
// if (length == 3)
// {
// SwapIfGreater(items, ref comparer, 0, 1);
// SwapIfGreater(items, ref comparer, 0, 2);
// SwapIfGreater(items, ref comparer, 1, 2);
// return;
// }
//
// OptimizedBubbleSort_Unchecked(items, length, ref comparer);
//}
}
}