Différences entre C ++ ssortingng == et compare ()?

Je viens de lire quelques recommandations sur l’utilisation

std::ssortingng s = get_ssortingng(); std::ssortingng t = another_ssortingng(); if( !s.compare(t) ) { 

au lieu de

 if( s == t ) { 

J’utilise presque toujours le dernier parce que j’y suis habitué et que ça semble naturel, plus lisible. Je ne savais même pas qu’il existait une fonction de comparaison distincte. Pour être plus précis, je pensais que == appellerait compare ().

Quelles sont les différences? Dans quels contextes une manière devrait-elle être privilégiée par rapport à l’autre?

Je ne considère que les cas où j’ai besoin de savoir si une chaîne a la même valeur qu’une autre chaîne.

C’est ce que dit le standard sur l’ operator==

21.4.8.2 opérateur ==

 template bool operator==(const basic_ssortingng& lhs, const basic_ssortingng& rhs) noexcept; 

Renvoie: lhs.compare (rhs) == 0.

On dirait qu’il n’y a pas beaucoup de différence!

std :: ssortingng :: compare () retourne un int :

  • égal à zéro si s et t sont égaux,
  • moins que zéro si s est inférieur à t ,
  • supérieur à zéro si s est supérieur à t .

Si vous voulez que votre premier extrait de code soit équivalent au second, il devrait en fait lire:

 if (!s.compare(t)) { // 's' and 't' are equal. } 

L’opérateur d’égalité ne teste que l’égalité (d’où son nom) et renvoie un bool .

Pour élaborer sur les cas d’utilisation, compare() peut être utile si vous êtes intéressé par la relation entre les deux chaînes (plus ou moins) lorsqu’elles sont différentes. PlasmaHH mentionne à juste titre les arbres, et il pourrait également s’agir, par exemple, d’un algorithme d’insertion de chaînes visant à conserver le conteneur sortingé, un algorithme de recherche dichotomique pour le conteneur susmentionné, etc.

EDIT: Comme Steve Jessop le fait remarquer dans les commentaires, compare() est le plus utile pour les algorithmes de sorting rapide et de recherche binary. Les sortes naturelles et les recherches dichotomiques peuvent être implémentées avec seulement std :: less .

compare a des surcharges pour comparer des sous-chaînes. Si vous comparez des chaînes entières, vous devez simplement utiliser l’opérateur == (et si elles appellent une compare ou non, cela n’a aucune importance).

En interne, ssortingng :: operator == () utilise ssortingng :: compare (). Veuillez vous référer à: CPlusPlus – Ssortingng :: Operator == ()

J’ai écrit une petite application pour comparer les performances, et apparemment, si vous comstackz et exécutez votre code sur un environnement de débogage, Ssortingng :: compare () est légèrement plus rapide que ssortingng :: operator == (). Cependant, si vous comstackz et exécutez votre code dans l’environnement Release, les deux sont à peu près les mêmes.

FYI, j’ai couru 1 000 000 d’itérations pour arriver à une telle conclusion.

Afin de prouver pourquoi dans l’environnement de débogage la chaîne :: compare est plus rapide, je suis allé à l’assemblage et voici le code:

DÉBOGAGE

ssortingng :: operator == ()

  if (str1 == str2) 00D42A34 lea eax,[str2] 00D42A37 push eax 00D42A38 lea ecx,[str1] 00D42A3B push ecx 00D42A3C call std::operator==,std::allocator > (0D23EECh) 00D42A41 add esp,8 00D42A44 movzx edx,al 00D42A47 test edx,edx 00D42A49 je Algorithm::PerformanceTest::ssortingngComparison_usingEqualOperator1+0C4h (0D42A54h) 

ssortingng :: compare ()

  if (str1.compare(str2) == 0) 00D424D4 lea eax,[str2] 00D424D7 push eax 00D424D8 lea ecx,[str1] 00D424DB call std::basic_ssortingng,std::allocator >::compare (0D23582h) 00D424E0 test eax,eax 00D424E2 jne Algorithm::PerformanceTest::ssortingngComparison_usingCompare1+0BDh (0D424EDh) 

Vous pouvez le voir dans ssortingng :: operator == (), il doit effectuer des opérations supplémentaires (add esp, 8 et movzx edx, al)

RELEASE BUILD

ssortingng :: operator == ()

  if (str1 == str2) 008533F0 cmp dword ptr [ebp-14h],10h 008533F4 lea eax,[str2] 008533F7 push dword ptr [ebp-18h] 008533FA cmovae eax,dword ptr [str2] 008533FE push eax 008533FF push dword ptr [ebp-30h] 00853402 push ecx 00853403 lea ecx,[str1] 00853406 call std::basic_ssortingng,std::allocator >::compare (0853B80h) 

ssortingng :: compare ()

  if (str1.compare(str2) == 0) 00853830 cmp dword ptr [ebp-14h],10h 00853834 lea eax,[str2] 00853837 push dword ptr [ebp-18h] 0085383A cmovae eax,dword ptr [str2] 0085383E push eax 0085383F push dword ptr [ebp-30h] 00853842 push ecx 00853843 lea ecx,[str1] 00853846 call std::basic_ssortingng,std::allocator >::compare (0853B80h) 

Les deux codes d’assemblage sont très similaires, car le compilateur effectue l’optimisation.

Enfin, à mon avis, le gain de performance est négligeable, donc je laisserais vraiment au développeur le soin de décider lequel est le meilleur car les deux obtiennent le même résultat (surtout quand il est construit).

compare() renverra false (enfin, 0 ) si les chaînes sont égales.

Alors ne prenez pas un échange léger pour l’autre.

Utilisez ce qui rend le code plus lisible.

compare() est équivalent à strcmp (). == est une vérification d’égalité simple. compare() renvoie donc un int , == est un booléen.

Si vous voulez juste vérifier l’égalité des chaînes, utilisez l’opérateur ==. Déterminer si deux chaînes sont égales est plus simple que de trouver un ordre (qui est ce que compare (), donc il peut être préférable, dans votre cas, d’utiliser l’opérateur d’égalité.

Réponse plus longue: L’API fournit une méthode pour vérifier l’égalité des chaînes et une méthode pour vérifier l’ordre des chaînes. Vous voulez une égalité de chaîne, utilisez donc l’opérateur d’égalité (pour que vos attentes et celles des implémenteurs de la bibliothèque soient alignées). Si les performances sont importantes, vous pouvez tester les deux méthodes et les trouver plus rapidement.

Une chose qui n’est pas couverte ici est que cela dépend si nous comparons la chaîne à la chaîne c, la chaîne c à la chaîne ou la chaîne à la chaîne.

Une différence majeure est que, pour comparer deux chaînes de caractères, l’égalité de taille est vérifiée avant de faire la comparaison, ce qui rend l’opérateur == plus rapide qu’une comparaison.

voici la comparaison telle que je le vois sur g ++ Debian 7

 // operator == /** * @brief Test equivalence of two ssortingngs. * @param __lhs First ssortingng. * @param __rhs Second ssortingng. * @return True if @a __lhs.compare(@a __rhs) == 0. False otherwise. */ template inline bool operator==(const basic_ssortingng<_CharT, _Traits, _Alloc>& __lhs, const basic_ssortingng<_CharT, _Traits, _Alloc>& __rhs) { return __lhs.compare(__rhs) == 0; } template inline typename __gnu_cxx::__enable_if<__is_char<_chart>::__value, bool>::__type operator==(const basic_ssortingng<_chart>& __lhs, const basic_ssortingng<_chart>& __rhs) { return (__lhs.size() == __rhs.size() && !std::char_traits<_chart>::compare(__lhs.data(), __rhs.data(), __lhs.size())); } /** * @brief Test equivalence of C ssortingng and ssortingng. * @param __lhs C ssortingng. * @param __rhs Ssortingng. * @return True if @a __rhs.compare(@a __lhs) == 0. False otherwise. */ template inline bool operator==(const _CharT* __lhs, const basic_ssortingng<_CharT, _Traits, _Alloc>& __rhs) { return __rhs.compare(__lhs) == 0; } /** * @brief Test equivalence of ssortingng and C ssortingng. * @param __lhs Ssortingng. * @param __rhs C ssortingng. * @return True if @a __lhs.compare(@a __rhs) == 0. False otherwise. */ template inline bool operator==(const basic_ssortingng<_CharT, _Traits, _Alloc>& __lhs, const _CharT* __rhs) { return __lhs.compare(__rhs) == 0; } 

Dans le débogueur Visual Studio 2012, seules les opérations suivantes fonctionnent correctement lorsque la vérification d’une chaîne est vide ou non:

 strcmp(somessortingng.c_str(),"")==0 

retourne vrai.

 somessortingng.compare("") 

retourne 1 et

 somessortingng=="" 

return: aucun opérateur “==” ne correspond à ces opérandes.

 somessortingng.c_str()=="" 

return: Une erreur non spécifiée s’est produite.

Supposons que l’on considère deux chaînes s et t.
Donnez-leur des valeurs.
Lorsque vous les comparez en utilisant (s == t), il retourne une valeur booléenne (true ou false, 1 ou 0).
Mais lorsque vous comparez en utilisant s.compare (t) , l’expression renvoie une valeur
(i) 0 – si s et t sont égaux
(ii) <0 – si la valeur du premier caractère sans correspondance dans s est inférieure à celle de t ou si la longueur de s est inférieure à celle de t.
(iii) > 0 – soit si la valeur du premier caractère non apparié dans t est inférieure à celle de s ou si la longueur de t est inférieure à celle de s.