Avec un tableau donné des noms de fichiers, la plus simple façon de trier par extension de fichier est comme ceci:Améliorer les performances de tri des fichiers par extension
Array.Sort(fileNames,
(x, y) => Path.GetExtension(x).CompareTo(Path.GetExtension(y)));
Le problème est que sur très longue liste (~ 800k Il faut beaucoup de temps pour trier, alors que le tri par le nom de fichier entier est plus rapide pour quelques secondes! Théorique, il existe un moyen de l'optimiser: au lieu d'utiliser Path.GetExtension()
et de comparer les nouvelles extensions uniquement, nous pouvons fournir une comparaison comparant les chaînes de fichiers existantes à partir du LastIndexOf('.')
sans créer de nouvelles chaînes.
Maintenant, supposons que j'ai trouvé le LastIndexOf('.')
, je veux réutiliser le StringComparer natif de .NET et l'appliquer seulement à la partie sur la chaîne après le LastIndexOf('.')
, pour préserver toute considération de culture. N'a pas trouvé un moyen de le faire.
Des idées?
Edit:
Avec l'idée de tanascius d'utiliser la méthode char.CompareTo()
, je suis venu avec mon Uber-Fast-File-Extension-Comparer, maintenant le tri par extension 3x fois plus rapide! il est encore plus rapide que toutes les méthodes qui utilisent Path.GetExtension()
d'une certaine manière. Qu'est-ce que tu penses?
Edit 2:
Je trouve que cette mise en œuvre n'envisage la culture depuis la méthode char.CompareTo()
ne considérer la culture, donc ce n'est pas une solution parfaite.
Des idées?
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;
}
}
Voir ma réponse éditée ... votre code peut être amélioré en implémentant une meilleure logique de branche (moins ifs dans le chemin du code commun). Pour activer une culture, vous devez lancer un char sur une corde, ce qui malheureusement ralentira tout. – tanascius