Właśnie przeczytałem kilka zaleceń dotyczących używania
std::string s = get_string();
std::string t = another_string();
if( !s.compare(t) )
{
zamiast
if( s == t )
{
Prawie zawsze używam ostatniego, ponieważ jestem do tego przyzwyczajony i wydaje mi się to naturalne, bardziej czytelne. Nawet nie wiedziałem, że istnieje osobna funkcja porównania. Mówiąc ściślej, pomyślałem, że == wywoła funkcję Compare ().
Jakie są różnice? W jakich kontekstach należy preferować jeden sposób na drugi?
Rozważam tylko przypadki, w których muszę wiedzieć, czy łańcuch ma taką samą wartość jak inny łańcuch.
if(x.compare(y) == 0)
<- znak równości, jest równy. Używanie IMO!
służy tylko do tego, aby kod był nieczytelny.compare
zwrot,-1
jeślis
jest niższy niżt
i+1
jeślis
jest większy niżt
podczas==
powrotutrue/false
. Niezerowe liczby całkowite sątrue
i0
sąfalse
.Odpowiedzi:
O tym mówi standard
operator==
Wygląda na to, że nie ma dużej różnicy!
źródło
!s.compare(t)
is == t
zwróci tę samą wartość, ale funkcja porównywania dostarcza więcej informacjis == t
is == t
jest bardziej czytelna, gdy nie obchodzi cię, jak różnią się ciągi, ale tylko jeśli się różnią.std :: string :: Compare () zwraca an
int
:s
it
są równe,s
jest mniejsze niżt
,s
jest większy niżt
.Jeśli chcesz, aby pierwszy fragment kodu był równoważny z drugim, powinien on w rzeczywistości brzmieć:
Operator równości sprawdza tylko równość (stąd jego nazwa) i zwraca a
bool
.Rozwinięcie przypadków użycia
compare()
może być przydatne, jeśli interesuje Cię, w jaki sposób te dwa ciągi odnoszą się do siebie (mniej lub więcej), kiedy są różne. PlasmaHH słusznie wspomina o drzewach, może to być również, powiedzmy, algorytm wstawiania ciągów, który ma na celu utrzymanie sortowania kontenera, dychotomiczny algorytm wyszukiwania dla wspomnianego wyżej kontenera i tak dalej.EDYCJA: Jak zauważa Steve Jessop w komentarzach,
compare()
jest najbardziej przydatny do algorytmów szybkiego sortowania i wyszukiwania binarnego. Naturalne sortowanie i wyszukiwania dychotomiczne mogą być realizowane tylko przy pomocy std :: less .źródło
std::less
w tym przypadku, która jest również całkowitą kolejnością) zamiast trójstronnego komparatora .compare()
jest dla operacji wzorowanych nastd::qsort
istd::bsearch
, w przeciwieństwie do operacji wzorowanych nastd:sort
istd::lower_bound
.compare
ma przeciążenia do porównywania podciągów. Jeśli porównujesz całe ciągi znaków, powinieneś po prostu użyć==
operatora (i to, czy wywołuje,compare
czy nie, nie ma większego znaczenia).źródło
Wewnętrznie
string::operator==()
używastring::compare()
. Proszę odnieść się do: CPlusPlus -string::operator==()
Napisałem małą aplikację do porównania wydajności i najwyraźniej jeśli skompilujesz i uruchomisz swój kod w środowisku debugowania,
string::compare()
jest to nieco szybsze niżstring::operator==()
. Jednak jeśli skompilujesz i uruchomisz kod w środowisku Release, oba są prawie takie same.Do Twojej wiadomości przeprowadziłem 1 000 000 iteracji, aby dojść do takiego wniosku.
Aby udowodnić, dlaczego w środowisku debugowania łańcuch :: porównywanie jest szybszy, poszedłem do zestawu i oto kod:
DEBUGOWANY BUDYNEK
string :: operator == ()
string :: porównaj ()
Widać, że w string :: operator == () musi wykonywać dodatkowe operacje (dodać esp, 8 i movzx edx, al)
ZWOLNIENIE BUDYNKU
string :: operator == ()
string :: porównaj ()
Oba kody zestawu są bardzo podobne, ponieważ kompilator wykonuje optymalizację.
Wreszcie, moim zdaniem, wzrost wydajności jest znikomy, dlatego naprawdę pozostawiłbym programistom decyzję, który z nich jest preferowany, ponieważ oba osiągają ten sam wynik (szczególnie, gdy jest to kompilacja wydania).
źródło
compare()
jest równoważne strcmp ().==
to proste sprawdzanie równości.compare()
dlatego zwraca anint
,==
boolean.źródło
compare()
zwrócifalse
(cóż,0
) jeśli łańcuchy są równe.Więc nie lekceważ jednego za drugiego.
Użyj tego, co czyni kod bardziej czytelnym.
źródło
Jeśli chcesz tylko sprawdzić równość łańcucha, użyj operatora ==. Ustalenie, czy dwa ciągi są równe, jest prostsze niż znalezienie uporządkowania (co daje porównanie ()), więc w twoim przypadku może być lepiej pod względem wydajności użycie operatora równości.
Dłuższa odpowiedź: interfejs API zapewnia metodę sprawdzania równości ciągów oraz metodę sprawdzania kolejności ciągów. Chcesz równości łańcuchów, więc użyj operatora równości (aby dopasować swoje oczekiwania i implementatory bibliotek). Jeśli wydajność jest ważna, możesz przetestować obie metody i znaleźć najszybszą.
źródło
Załóżmy, że rozważmy dwa ciągi si t.
Podaj im pewne wartości.
Kiedy porównasz je za pomocą (s == t) , zwraca wartość logiczną (prawda lub fałsz, 1 lub 0).
Ale gdy porównujesz za pomocą s.compare (t) , wyrażenie zwraca wartość
(i) 0 - jeśli si it są równe
(ii) <0 - albo jeśli wartość pierwszego niedopasowanego znaku w s jest mniejsza niż wartość t lub długość s jest mniejsza niż długość t.
(iii) > 0 - jeśli wartość pierwszego niedopasowanego znaku wt jest mniejsza niż s lub długość t jest mniejsza niż s.
źródło
Jedną rzeczą, która nie jest tutaj omawiana, jest to, że zależy to od porównania łańcucha do łańcucha c, łańcucha do łańcucha lub łańcucha do łańcucha.
Główną różnicą jest to, że do porównania dwóch łańcuchów równość wielkości jest sprawdzana przed wykonaniem porównania, co sprawia, że operator == jest szybszy niż porównanie.
oto porównanie, jakie widzę na g ++ Debian 7
źródło