programing

C++ 문자열 ==과 비교()의 차이점은 무엇입니까?

mailnote 2023. 5. 26. 22:08
반응형

C++ 문자열 ==과 비교()의 차이점은 무엇입니까?

사용에 대한 몇 가지 권장 사항을 방금 읽었습니다.

std::string s = get_string();
std::string t = another_string();

if( !s.compare(t) ) 
{

대신에

if( s == t )
{

저는 거의 항상 마지막 것을 사용합니다. 왜냐하면 저는 그것에 익숙하고 자연스럽고, 더 읽기 쉽게 느껴지기 때문입니다.저는 비교 기능이 따로 있는지도 몰랐습니다.좀 더 정확히 말하자면, 저는 ==가 compare를 부를 것이라고 생각했습니다.

어떤 차이가 있을까?어떤 맥락에서 한 쪽이 다른 쪽에 유리해야 합니까?

문자열이 다른 문자열과 같은 값인지 알아야 하는 경우만 고려하고 있습니다.

이 이이표이말것다입니하는준에 대해 입니다.operator==

21.4.8.2 조작자 ==

template<class charT, class traits, class Allocator>
bool operator==(const basic_string<charT,traits,Allocator>& lhs,
                const basic_string<charT,traits,Allocator>& rhs) noexcept;

반환값: lhs.lhs(rhs) == 0.

별 차이가 없는 것 같아요!

std::string::startup은 다음을 반환합니다.int:

  • 0인 경우 s그리고.t 동등합니 다▁are등다.
  • 0인 경우 s보다 .t,
  • 인 경우 보다 큼s보다 큼t.

첫 번째 코드 조각을 두 번째 코드 조각과 동일하게 하려면 실제로 다음을 읽어야 합니다.

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

equality(즉, equality하고 equality를 합니다.bool.

사례를 하자면, 사용사례자설면자하명세히를,면자▁to,compare()두 문자열이 서로 다른 경우 두 문자열이 서로(적거나 더 큰) 어떻게 관계되는지 관심이 있는 경우 유용할 수 있습니다.PlasmaH는 나무를 올바르게 언급하고, 예를 들어, 컨테이너를 정렬 상태로 유지하는 것을 목표로 하는 문자열 삽입 알고리즘, 전술한 컨테이너에 대한 이분법적 검색 알고리즘 등이 될 수 있습니다.

편집: Steve Jessop이 댓글에서 지적했듯이,compare()빠른 정렬 및 이진 검색 알고리즘에 가장 유용합니다.자연 정렬 및 이분법적 검색은 std::less로만 구현할 수 있습니다.

내적으로.string::operator==() 중입니다.string::compare()다음을 참조하십시오: CPluxPlus -

성능을 비교하기 위해 작은 애플리케이션을 작성했는데, 디버그 환경에서 코드를 컴파일하고 실행하면string::compare() 약빠름보다 약간 .string::operator==()그러나 릴리스 환경에서 코드를 컴파일하고 실행하면 둘 다 거의 동일합니다.

참고로, 저는 그러한 결론을 내기 위해 1,000,000번의 반복을 실행했습니다.

디버그 환경에서 문자열::compare가 더 빠른 이유를 증명하기 위해 어셈블리로 가서 코드를 확인했습니다.

디버그 빌드

문자열:filename==filename

        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)  

문자열:예:예:예

            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)

문자열::sys==sys에서 추가 작업을 수행해야 함을 알 수 있습니다(addesp, 8 및 movzx edx, al).

빌드 릴리스

문자열:filename==filename

        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)  

문자열:예:예:예

            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)

컴파일러가 최적화를 수행할 때 두 어셈블리 코드는 매우 유사합니다.

마지막으로, 성능 향상은 무시할 수 있는 수준이므로, 둘 다 동일한 결과를 얻기 때문에(특히 릴리스 빌드일 때) 어떤 것이 선호되는지 결정하는 것은 개발자에게 맡깁니다.

compare하위 문자열을 비교하기 위한 오버로드가 있습니다.는 전체문자을비경는사우합는니용다야해에교하열▁use합다니▁if▁just▁you사▁whole를 사용해야 합니다.== 연자및산(출호여부및여))를 호출하는지 )compare또는 거의 무관하지 않음).

compare()strcmp³같다니습와▁▁tostr▁equival에 해당합니다. ==단순한 동일성 검사입니다. compare() 반환합니다.int,==는 부울입니다.

compare()돌아올 것입니다false(글쎄요,0문자열이 동일한 경우.

그러니 하나를 다른 하나와 교환하는 것을 가볍게 여기지 마세요.

코드를 더 읽기 쉽게 만드는 것 중 하나를 사용합니다.

문자열 동일성만 확인하려면 == 연산자를 사용합니다.두 문자열이 동일한지 여부를 확인하는 것은 순서(비교()가 제공하는 것)를 찾는 것보다 간단하므로 동일 연산자를 사용하는 것이 성능 측면에서 더 나을 수 있습니다.

긴 답변:API는 문자열 동일성을 확인하는 방법과 문자열 순서를 확인하는 방법을 제공합니다.문자열 동일성을 원하는 경우 equal 연산자를 사용합니다(사용자의 기대와 라이브러리 구현자의 기대가 일치하도록).성능이 중요한 경우 두 가지 방법을 모두 테스트하여 가장 빠른 방법을 찾을 수 있습니다.

여기서 다루지 않은 한 가지는 문자열을 c 문자열로, c 문자열을 문자열로, 또는 문자열을 문자열로 비교하는지에 따라 다르다는 것입니다.

가장 큰 차이점은 비교를 수행하기 전에 두 문자열의 크기가 동일한지 여부를 확인하고 이를 통해 == 연산자가 비교보다 빠르다는 것입니다.

여기 제가 g++ 데비안 7에서 본 비교가 있습니다.

// operator ==
  /**
   *  @brief  Test equivalence of two strings.
   *  @param __lhs  First string.
   *  @param __rhs  Second string.
   *  @return  True if @a __lhs.compare(@a __rhs) == 0.  False otherwise.
   */
  template<typename _CharT, typename _Traits, typename _Alloc>
    inline bool
    operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
    { return __lhs.compare(__rhs) == 0; }

  template<typename _CharT>
    inline
    typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, bool>::__type
    operator==(const basic_string<_CharT>& __lhs,
           const basic_string<_CharT>& __rhs)
    { return (__lhs.size() == __rhs.size()
          && !std::char_traits<_CharT>::compare(__lhs.data(), __rhs.data(),
                            __lhs.size())); }

  /**
   *  @brief  Test equivalence of C string and string.
   *  @param __lhs  C string.
   *  @param __rhs  String.
   *  @return  True if @a __rhs.compare(@a __lhs) == 0.  False otherwise.
   */
  template<typename _CharT, typename _Traits, typename _Alloc>
    inline bool
    operator==(const _CharT* __lhs,
           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
    { return __rhs.compare(__lhs) == 0; }

  /**
   *  @brief  Test equivalence of string and C string.
   *  @param __lhs  String.
   *  @param __rhs  C string.
   *  @return  True if @a __lhs.compare(@a __rhs) == 0.  False otherwise.
   */
  template<typename _CharT, typename _Traits, typename _Alloc>
    inline bool
    operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
           const _CharT* __rhs)
    { return __lhs.compare(__rhs) == 0; }

두 개의 문자열과 t를 생각해 보겠습니다.
그들에게 몇 가지 가치를 주세요.
(s==t)를 사용하여 비교하면 부울 값(참 또는 거짓, 1 또는 0)이 반환됩니다.
그러나 s.compare(t)사용하여 비교할 때 식은 다음 값을 반환합니다.
0 - s와 t가 같은 경우
(ii) <0 - s에서 첫 번째 일치하지 않는 문자의 값이 t의 값보다 작거나 s의 길이가 t의 값보다 작은 경우.
(iii) >0 - t의 첫 번째 일치하지 않는 문자 값이 s보다 작거나 t의 길이가 s보다 작은 경우.

언급URL : https://stackoverflow.com/questions/9158894/differences-between-c-string-and-compare

반응형