Given a given array of file names, the easiest way to sort by file extension is as follows:
Array.Sort(fileNames, (x, y) => Path.GetExtension(x).CompareTo(Path.GetExtension(y)));
The problem is that a very long list (~ 800k) takes a lot of time to sort, and sorting by the whole file name is faster by a couple of seconds!
Theoretically, there is a way to optimize it: instead of using Path.GetExtension() and comparing newly created lines only for extension, we can provide a comparison than comparing existing lines of file names starting with LastIndexOf('.') Without creating new lines.
Now suppose I found LastIndexOf('.') , I want to reuse my own .NET StringComparer and apply it only to the part on the line after LastIndexOf('.') To preserve all aspects of the culture. Did not find a way to do this.
Any ideas?
Edit:
With the idea of ββtanascius to use the char.CompareTo() method, I came up with my Uber-Fast-File-Extension-Comparer, now it is sorted by extension 3 times faster! it is even faster than all methods that use Path.GetExtension() in some way. what do you think?
Edit 2:
I found that this implementation does not consider culture, since the char.CompareTo() method does not consider culture, so this is not an ideal solution.
Any ideas?
public static int CompareExtensions(string filePath1, string filePath2) { if (filePath1 == null && filePath2 == null) { return 0; } else if (filePath1 == null) { return -1; } else if (filePath2 == null) { return 1; } int i = filePath1.LastIndexOf('.'); int j = filePath2.LastIndexOf('.'); if (i == -1) { i = filePath1.Length; } else { i++; } if (j == -1) { j = filePath2.Length; } else { j++; } for (; i < filePath1.Length && j < filePath2.Length; i++, j++) { int compareResults = filePath1[i].CompareTo(filePath2[j]); if (compareResults != 0) { return compareResults; } } if (i >= filePath1.Length && j >= filePath2.Length) { return 0; } else if (i >= filePath1.Length) { return -1; } else { return 1; } }
Dxck
source share