Upper vs Lower Case

Lors de comparaisons insensibles à la casse, est-il plus efficace de convertir la chaîne en majuscule ou en minuscule? Est-ce même important?

Il est suggéré dans cet article SO que C # est plus efficace avec ToUpper car “Microsoft l’a optimisé de cette façon”. Mais j’ai aussi lu cet argument selon lequel la conversion de ToLower contre ToUpper dépend de ce que vos chaînes contiennent de plus, et que les chaînes contiennent généralement plus de minuscules, ce qui rend ToLower plus efficace.

En particulier, j’aimerais savoir:

  • Y a-t-il un moyen d’optimiser ToUpper ou ToLower de manière à ce que l’un soit plus rapide que l’autre?
  • Est-il plus rapide de faire une comparaison insensible à la casse entre les chaînes majuscules et minuscules et pourquoi?
  • Existe-t-il des environnements de programmation (par exemple, C, C #, Python, etc.) où un cas est clairement meilleur que l’autre et pourquoi?

La conversion en majuscules ou en minuscules pour effectuer des comparaisons insensibles à la casse est incorrecte en raison de caractéristiques “intéressantes” de certaines cultures, en particulier de la Turquie. Au lieu de cela, utilisez un SsortingngComparer avec les options appropriées.

MSDN contient de bonnes directives sur la gestion des chaînes. Vous pouvez également vérifier que votre code réussit le test Turquie .

EDIT: Notez le commentaire de Neil sur les comparaisons ordinales insensibles à la casse. Tout ce royaume est assez trouble 🙁

De Microsoft sur MSDN:

Meilleures pratiques pour l’utilisation de chaînes dans le .NET Framework

Recommandations pour l’utilisation des chaînes

  • Utilisez la méthode Ssortingng.ToUpperInvariant au lieu de la méthode Ssortingng.ToLowerInvariant lorsque vous normalisez des chaînes à des fins de comparaison.

Pourquoi? De Microsoft :

Normaliser les chaînes en majuscules

Il y a un petit groupe de caractères qui, convertis en minuscules, ne peuvent pas faire un aller-retour.

Quel est l’exemple d’un tel personnage qui ne peut pas faire un aller-retour?

  • Début : Symbole grec de Rho (U + 03f1) ϱ
  • Majuscule: majuscule grecque Rho (U + 03a1) Ρ
  • Minuscule: petit grec Rho (U + 03c1) ρ

ϱ, Ρ , ρ

C’est pourquoi, si vous voulez faire des comparaisons insensibles à la casse, convertissez les chaînes en majuscules et non en minuscules.

Selon MSDN, il est plus efficace de passer les chaînes et d’indiquer à la comparaison d’ignorer la casse:

Ssortingng.Compare (strA, strB, SsortingngComparison.OrdinalIgnoreCase) est équivalent à ( mais plus rapide que ) l’appel

Ssortingng.Compare (ToUpperInvariant (strA), ToUpperInvariant (strB), SsortingngComparison.Ordinal).

Ces comparaisons sont encore très rapides.

Bien sûr, si vous comparez une chaîne à plusieurs resockets, cela peut ne pas être le cas.

Basé sur des chaînes ayant tendance à avoir plus d’entrées minuscules, ToLower devrait théoriquement être plus rapide (beaucoup de comparaisons, mais peu d’assignations).

En C, ou en utilisant des éléments accessibles individuellement de chaque chaîne (tels que les chaînes C ou le type de chaîne de la STL en C ++), il s’agit en fait d’une comparaison d’octets.

Si vous étiez sournois et que vous chargiez vos chaînes dans de long tableaux, vous obtiendriez une comparaison très rapide sur toute la chaîne, car elle pourrait comparer 4 octets à la fois. Cependant, le temps de chargement peut ne pas en valoir la peine.

Pourquoi avez-vous besoin de savoir qui est le plus rapide? À moins que vous ne fassiez un calcul mésortingque des comparaisons, celui qui exécute deux cycles plus rapidement n’a aucune importance sur la vitesse d’exécution générale, et sonne comme une optimisation prématurée 🙂

Microsoft a optimisé ToUpperInvariant() , pas ToUpper() . La différence est que l’invariant est plus favorable à la culture. Si vous avez besoin de faire des comparaisons insensibles à la casse sur des chaînes dont la culture peut varier, utilisez Invariant, sinon les performances de la conversion invariante ne devraient pas avoir d’importance.

Je ne peux pas dire si ToUpper () ou ToLower () est plus rapide cependant. Je ne l’ai jamais essayé car je n’ai jamais eu une situation où la performance comptait beaucoup.

Si vous faites une comparaison de chaînes en C #, il est beaucoup plus rapide d’utiliser .Equals () au lieu de convertir les deux chaînes en majuscules ou en minuscules. Un autre gros avantage de l’utilisation de .Equals () est que plus de mémoire n’est pas allouée aux 2 nouvelles chaînes majuscules / minuscules.

Ça ne devrait vraiment jamais avoir d’importance. Avec les caractères ASCII, cela n’a pas d’importance – ce ne sont que quelques comparaisons et un peu d’inversion dans les deux sens. Unicode est peut-être un peu plus compliqué, car certains caractères changent de manière étrange, mais il ne devrait y avoir aucune différence à moins que votre texte ne soit rempli de ces caractères spéciaux.

En procédant correctement, il devrait y avoir un petit avantage de vitesse insignifiant si vous convertissez en minuscule, mais c’est, comme beaucoup l’ont laissé entendre, dépendant de la culture et non hérité dans la fonction mais dans les chaînes que vous convertissez (beaucoup de lettres minuscules) signifie peu d’atsortingbutions à la mémoire) – la conversion en majuscule est plus rapide si vous avez une chaîne avec beaucoup de lettres majuscules.

Ça dépend. Comme indiqué ci-dessus, uniquement ASCII, c’est identique. Dans .NET, lisez et utilisez Ssortingng.Compare son correct pour le truc i18n (langues cultures et Unicode). Si vous savez quelque chose sur la probabilité de saisie, utilisez le cas le plus courant.

N’oubliez pas que si vous effectuez plusieurs comparaisons de chaînes, c’est un excellent premier discriminateur.

Si vous traitez en ASCII pur, cela n’a pas d’importance. C’est juste un OR x, 32 contre un AND x, 224. Unicode, je n’en ai aucune idée …