对于给定的文件名数组,按文件扩展名对其进行排序的最简单方法如下:
Array.Sort(fileNames,
(x, y) => Path.GetExtension(x).CompareTo(Path.GetExtension(y)));
问题是在很长的列表(~800k)上排序需要很长时间,而按整个文件名排序会更快几秒钟!
理论上,有一种方法可以优化它:Path.GetExtension()
我们可以提供一个比较,而不是使用和比较新创建的仅扩展名字符串,而不是比较现有的文件名字符串,LastIndexOf('.')
而不创建新的字符串。
现在,假设我找到了LastIndexOf('.')
,我想重用本机 .NET 的 StringComparer 并将其仅应用于 之后的字符串部分LastIndexOf('.')
,以保留所有文化考虑。没有找到办法做到这一点。
有任何想法吗?
编辑:
有了 tanascius 使用char.CompareTo()
方法的想法,我带来了我的 Uber-Fast-File-Extension-Comparer,现在它按扩展名排序快了 3 倍!它甚至比Path.GetExtension()
以某种方式使用的所有方法都快。你怎么看?
编辑2:
我发现这个实现不考虑文化,因为char.CompareTo()
方法不考虑文化,所以这不是一个完美的解决方案。
有任何想法吗?
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;
}
}