Differences between C++ string == and compare()?
Solution 1
This is what the standard has to say about operator==
21.4.8.2 operator==
template<class charT, class traits, class Allocator> bool operator==(const basic_string<charT,traits,Allocator>& lhs, const basic_string<charT,traits,Allocator>& rhs) noexcept;
Returns: lhs.compare(rhs) == 0.
Seems like there isn't much of a difference!
Solution 2
std::string::compare() returns an int
:
- equal to zero if
s
andt
are equal, - less than zero if
s
is less thant
, - greater than zero if
s
is greater thant
.
If you want your first code snippet to be equivalent to the second one, it should actually read:
if (!s.compare(t)) {
// 's' and 't' are equal.
}
The equality operator only tests for equality (hence its name) and returns a bool
.
To elaborate on the use cases, compare()
can be useful if you're interested in how the two strings relate to one another (less or greater) when they happen to be different. PlasmaHH rightfully mentions trees, and it could also be, say, a string insertion algorithm that aims to keep the container sorted, a dichotomic search algorithm for the aforementioned container, and so on.
EDIT: As Steve Jessop points out in the comments, compare()
is most useful for quick sort and binary search algorithms. Natural sorts and dichotomic searches can be implemented with only std::less.
Solution 3
Internally, string::operator==()
is using string::compare()
. Please refer to: CPlusPlus - string::operator==()
I wrote a small application to compare the performance, and apparently if you compile and run your code on debug environment the string::compare()
is slightly faster than string::operator==()
. However if you compile and run your code in Release environment, both are pretty much the same.
FYI, I ran 1,000,000 iteration in order to come up with such conclusion.
In order to prove why in debug environment the string::compare is faster, I went to the assembly and here is the code:
DEBUG BUILD
string::operator==()
if (str1 == str2)
00D42A34 lea eax,[str2]
00D42A37 push eax
00D42A38 lea ecx,[str1]
00D42A3B push ecx
00D42A3C call std::operator==<char,std::char_traits<char>,std::allocator<char> > (0D23EECh)
00D42A41 add esp,8
00D42A44 movzx edx,al
00D42A47 test edx,edx
00D42A49 je Algorithm::PerformanceTest::stringComparison_usingEqualOperator1+0C4h (0D42A54h)
string::compare()
if (str1.compare(str2) == 0)
00D424D4 lea eax,[str2]
00D424D7 push eax
00D424D8 lea ecx,[str1]
00D424DB call std::basic_string<char,std::char_traits<char>,std::allocator<char> >::compare (0D23582h)
00D424E0 test eax,eax
00D424E2 jne Algorithm::PerformanceTest::stringComparison_usingCompare1+0BDh (0D424EDh)
You can see that in string::operator==(), it has to perform extra operations (add esp, 8 and movzx edx,al)
RELEASE BUILD
string::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_string<char,std::char_traits<char>,std::allocator<char> >::compare (0853B80h)
string::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_string<char,std::char_traits<char>,std::allocator<char> >::compare (0853B80h)
Both assembly code are very similar as the compiler perform optimization.
Finally, in my opinion, the performance gain is negligible, hence I would really leave it to the developer to decide on which one is the preferred one as both achieve the same outcome (especially when it is release build).
Solution 4
compare
has overloads for comparing substrings. If you're comparing whole strings you should just use ==
operator (and whether it calls compare
or not is pretty much irrelevant).
Solution 5
compare()
is equivalent to strcmp(). ==
is simple equality checking. compare()
therefore returns an int
, ==
is a boolean.
Klaim
Updated on May 04, 2020Comments
-
Klaim about 4 years
I just read some recommendations on using
std::string s = get_string(); std::string t = another_string(); if( !s.compare(t) ) {
instead of
if( s == t ) {
I'm almost always using the last one because I'm used to it and it feels natural, more readable. I didn't even know that there was a separate comparison function. To be more precise, I thought == would call compare().
What are the differences? In which contexts should one way be favored to the other?
I'm considering only the cases where I need to know if a string is the same value as another string.
-
PlasmaHH over 12 yearsnote that this behaviour is often useful when dealing with trees or tree-like creatures.
-
Frédéric Hamidi over 12 yearsIndeed it is, I was only pointing out the differences between the method and the equality operator :)
-
PlasmaHH over 12 years"In which contexts should one way be favored to the other?" just makes me think the OP can't think of possible use-cases for compare().
-
Steve Jessop over 12 years"if you're interested in how the two strings relate to one another" -- although idiomatic C++ for this is to use a strict weak order (like
std::less
, which is also a total order in this case) rather than a three-way comparator.compare()
is for operations modeled onstd::qsort
andstd::bsearch
, as opposed to those modeled onstd:sort
andstd::lower_bound
. -
Dragos almost 9 yearscode is formatted and shown formatted in the editor. Display got it wrong. open basic_string.h and look for operator== on your OS. The code is not mine is standard, the fact that the size check is what is missing in this thread. I also see that lots of people agree with incorrect information which defies the utility of Stack Overflow.
-
xtofl over 8 years'very similar'... I see no difference, do you?
-
Wagner Patriota over 7 yearsme neither... they are the same thing. there's no difference
-
JulianHarty about 7 years@xtofl from Tony's example the generated codes are identical in the release build, they're different in the debug builds.
-
cdgraham about 5 yearsNote to readers: Please read Frédéric Hamidi's answer for details on the matter because there are relevant differences. Although I'm glad Bo Persson shows that the two tests will definitely return the same value.
!s.compare(t)
ands == t
will return the same value, but the compare function provides more information thans == t
, ands == t
is more readable when you don't care how the strings differ but only if they differ.