c # Le moyen le plus rapide de comparer les chaînes
J'ai remarqué que
string1.Length == string2.Length && string1 == string2
sur les grandes chaînes est légèrement plus rapide que seulement
string1 == string2
Est-ce vrai? Et est-ce une bonne pratique pour comparer de grandes longueurs de chaîne avant de la comparaison des chaînes de caractères?
source d'informationauteur CoolCodeBro
Vous devez vous connecter pour publier un commentaire.
string
s de l'opérateur est égal à la longueur de vérifier avant de comparer les caractères. Si vous n'enregistrez pas la comparaison du contenu avec ce truc. Vous pourrait encore gagner quelques cycles CPU parce que votre contrôle de la longueur suppose que les chaînes ne sont pas null, alors que la BCL doivent vérifier. Donc, si les longueurs ne sont pas égaux, la plupart du temps, vous court-circuit d'un peu d'instructions.J'ai peut-être mal ici, cependant. Peut-être que l'opérateur fait inline et les contrôles optimisés. Qui sait? (Celui qui mesures.)
Si vous vous souciez de sauver chaque cycle, vous pouvez, vous devriez probablement utiliser une stratégie différente en premier lieu. Peut-être géré code n'est même pas le bon choix. Étant donné que, je vous recommande d'utiliser la version la plus courte et ne pas utiliser le contrôle supplémentaire.
Chaîne de caractères.Opérateur D'Égalité ou
==
appelle en internestring.Equals
afin de l'utiliserstring.Égal à
ou==
fournies par le framework. Il est déjà assez optimisé.Il d'abord à comparer les références, puis de la longueur, puis des caractères réels.
Vous pouvez trouver le code source ici
Code: (Source: http://www.dotnetframework.org/default.aspx/4@0/4@0/DEVDIV_TFS/Dev10/Releases/RTMRel/ndp/clr/src/BCL/System/String@cs/1305376/String@cs)
et
Mes résultats de test
Comparer 10000 chaînes de 10000 autres chaînes, tous de la même longueur (256)
Temps (s1 == s2): 32536889 tiques
Temps (s1.Longueur == s2.La longueur) && (s1 == s2): 37380529 tiques
Comparer 10000 chaînes de 10000 autres chaînes de longueur Aléatoire max 256
Temps (s1 == s2): 27223517 tiques
Temps (s1.Longueur == s2.La longueur) && (s1 == s2): 23419529 tiques
Comparer 10000 chaînes de 10000 autres chaînes de longueur Aléatoire min 256 max 512
Temps (s1 == s2): 28904898 tiques
Temps (s1.Longueur == s2.La longueur) && (s1 == s2): 25442710 tiques
Ce que je trouve ahurissant, c'est que d'une comparaison de 10000 égalité des chaînes de caractères de longueur prendra plus de temps que de comparer la même quantité de données qui est plus grand.
Tous ces tests ont été fait avec exactement les mêmes données.
Selon ILSpy, la chaîne
==
opérateur est défini comme:Qui est définie comme
Je suppose que la première
a == b
est en fait une référence de contrôle d'égalité (ILSpy est juste rendu comme==
), sinon ce serait infiniment méthode récursive.Cela signifie que
==
déjà de vérifier les longueurs des cordes avant de comparer leurs personnages.Dans des chaînes terminées, il est logique de commencer la comparaison des caractères, puisque vous ne pouvez pas calculer la longueur de chaîne sans itération tous les caractères de toute façon, et la comparaison est susceptible de sortie précoce.
Avec la longueur des chaînes comptées, en comparant la longueur doit être fait en premier, si vous testez l'octet-sage de l'égalité. Vous ne pouvez même pas commencer à accéder aux données de caractère sans récupération de la longueur, car on peut être de longueur nulle.
Si vous faites un relationnel de comparaison, connaissant les longueurs sont différentes ne vous dit pas si le résultat doit être positif ou négatif. Et dans une culture-connaissance de la comparaison, de l'égalité des chaînes de caractères, n'implique pas l'égalité de longueurs. Donc, à la fois de ceux que vous avez juste besoin de comparer les données.
Si
operator==(string, string)
simplement délégués à un relationnel de comparaison, vous ne seriez pas s'attendre à ce que pour comparer des longueurs. Vérification de la longueur avant de faire la comparaison peut donc être un avantage. Mais il semble que le Cadre ne démarre avec un contrôle de la longueur.Pour les geeks d'entre nous, voici une page qui fait un excellent travail à l'analyse comparative de nombreux moyens pour comparer des chaînes.
En un mot, la méthode la plus rapide semble être le CompareOrdinal:
Le deuxième meilleur moyen semble être l'utilisation d'un Dictionnaire ou Hashset avec la "clé" que la chaîne de caractères que vous souhaitez comparer.
En fait une lecture intéressante.
Je dirais que la première est plus rapide est le résultat de
string1.Length == string2.Length
est faux. Grâce à de Court-Circuit d'Évaluation (SCE) la comparaison entre les cordes est alors pas fait, ce qui peut vous faire gagner du temps.Si les chaînes sont égales toutefois, le premier est plus lente car elle permet de vérifier la longueur en premier et ensuite faire la même chose que le deuxième.
Voir http://msdn.microsoft.com/en-us/library/2a723cdk.aspx pour plus d'informations sur le
&&
opérateur et SCE.Donc, comme je l'ai promis, j'ai écrit un petit code avec un chronomètre - vous pouvez copier coller et essayer sur différentes chaînes et de voir les différences
Mes conclusions:
Si vous vous attendez à ce que les cordes d'être différent dans leurs longueurs dans la plupart du temps, vous pouvez comparer leurs longueurs ET puis de comparer les chaînes de caractères en utilisant
string.Compare
. J'ai obtenu près de 50% d'amélioration de la performance en faisant ceci:Dans ce cas, j'attends les chaînes différentes, presque tout le temps, je pense que str1.La longueur est beaucoup moins cher que d'en comparant les cordes. Si ils sont de la même taille, j'ai les comparer.
MODIFIER: Oubliez ce que j'ai dit. Utilisez simplement
==
et d'être heureux.