diff --git a/AssetStudioGUI/AssetStudioGUIForm.cs b/AssetStudioGUI/AssetStudioGUIForm.cs index 0aaa307..c98da69 100644 --- a/AssetStudioGUI/AssetStudioGUIForm.cs +++ b/AssetStudioGUI/AssetStudioGUIForm.cs @@ -80,7 +80,12 @@ namespace AssetStudioGUI //asset list sorting private int sortColumn = -1; private bool reverseSort; + +#if NET6_0_OR_GREATER + private AlphanumComparatorFastNet alphanumComparator = new AlphanumComparatorFastNet(); +#else private AlphanumComparatorFast alphanumComparator = new AlphanumComparatorFast(); +#endif //asset list filter private System.Timers.Timer delayTimer; @@ -655,9 +660,10 @@ namespace AssetStudioGUI { visibleAssets.Sort((a, b) => { - var at = a.SubItems[sortColumn].Text; - var bt = b.SubItems[sortColumn].Text; - return reverseSort ? bt.CompareTo(at) : at.CompareTo(bt); + var at = a.SubItems[sortColumn].Text.AsSpan(); + var bt = b.SubItems[sortColumn].Text.AsSpan(); + + return reverseSort ? MemoryExtensions.CompareTo(bt, at, StringComparison.OrdinalIgnoreCase) : MemoryExtensions.CompareTo(at, bt, StringComparison.OrdinalIgnoreCase); }); } assetListView.EndUpdate(); diff --git a/AssetStudioGUI/Components/AlphanumComparatorFast.cs b/AssetStudioGUI/Components/AlphanumComparatorFast.cs index 7998344..e5ab2a6 100644 --- a/AssetStudioGUI/Components/AlphanumComparatorFast.cs +++ b/AssetStudioGUI/Components/AlphanumComparatorFast.cs @@ -1,22 +1,16 @@ -// This code developed by Dot Net Perls -using System.Collections; +// AlphanumComparatorFast mod by VaDiM +// Original code was developed by Dot Net Perls +// For more detail visit: https://www.dotnetperls.com/alphanumeric-sorting +using System; +using System.Collections.Generic; namespace AssetStudioGUI { - internal class AlphanumComparatorFast : IComparer + internal class AlphanumComparatorFast : IComparer { - public int Compare(object x, object y) + public int Compare(string s1, string s2) { - if (!(x is string s1)) - { - return 0; - } - if (!(y is string s2)) - { - return 0; - } - int len1 = s1.Length; int len2 = s2.Length; int marker1 = 0; @@ -69,20 +63,17 @@ namespace AssetStudioGUI // If we have collected numbers, compare them numerically. // Otherwise, if we have strings, compare them alphabetically. - string str1 = new string(space1); - string str2 = new string(space2); - int result; if (char.IsDigit(space1[0]) && char.IsDigit(space2[0])) { - int thisNumericChunk = int.Parse(str1); - int thatNumericChunk = int.Parse(str2); + int thisNumericChunk = int.Parse(new string(space1)); + int thatNumericChunk = int.Parse(new string(space2)); result = thisNumericChunk.CompareTo(thatNumericChunk); } else { - result = str1.CompareTo(str2); + result = MemoryExtensions.CompareTo(space1, space2, StringComparison.OrdinalIgnoreCase); } if (result != 0) diff --git a/AssetStudioGUI/Components/AlphanumComparatorFastNet.cs b/AssetStudioGUI/Components/AlphanumComparatorFastNet.cs new file mode 100644 index 0000000..bef12c0 --- /dev/null +++ b/AssetStudioGUI/Components/AlphanumComparatorFastNet.cs @@ -0,0 +1,93 @@ +// AlphanumComparatorFast mod by VaDiM +// Original code was developed by Dot Net Perls +// For more detail visit: https://www.dotnetperls.com/alphanumeric-sorting + +using System; +using System.Collections.Generic; + +#if NET6_0_OR_GREATER +namespace AssetStudioGUI +{ + internal class AlphanumComparatorFastNet : IComparer + { + public int Compare(string s1, string s2) + { + const int maxStackSize = 256; + int len1 = s1.Length; + int len2 = s2.Length; + int marker1 = 0; + int marker2 = 0; + + // Some buffers we can build up characters in for each chunk. + Span space1 = len1 > maxStackSize ? new char[len1] : stackalloc char[len1]; + Span space2 = len2 > maxStackSize ? new char[len2] : stackalloc char[len2]; + + // Walk through two the strings with two markers. + while (marker1 < len1 && marker2 < len2) + { + char ch1 = s1[marker1]; + char ch2 = s2[marker2]; + + int loc1 = 0; + int loc2 = 0; + space1.Clear(); + space2.Clear(); + + // Walk through all following characters that are digits or + // characters in BOTH strings starting at the appropriate marker. + // Collect char arrays. + do + { + space1[loc1++] = ch1; + marker1++; + + if (marker1 < len1) + { + ch1 = s1[marker1]; + } + else + { + break; + } + } while (char.IsDigit(ch1) == char.IsDigit(space1[0])); + + do + { + space2[loc2++] = ch2; + marker2++; + + if (marker2 < len2) + { + ch2 = s2[marker2]; + } + else + { + break; + } + } while (char.IsDigit(ch2) == char.IsDigit(space2[0])); + + // If we have collected numbers, compare them numerically. + // Otherwise, if we have strings, compare them alphabetically. + int result; + + if (char.IsDigit(space1[0]) && char.IsDigit(space2[0])) + { + int thisNumericChunk = int.Parse(space1); + int thatNumericChunk = int.Parse(space2); + result = thisNumericChunk.CompareTo(thatNumericChunk); + } + else + { + result = MemoryExtensions.CompareTo(space1, space2, StringComparison.OrdinalIgnoreCase); + } + + if (result != 0) + { + return result; + } + } + return len1 - len2; + } + } +} +#endif