<html>
    <head>
      <base href="http://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - string::operator==(const char *) unnecessarily computes rhs length, then doesn't take advantage of it"
   href="http://llvm.org/bugs/show_bug.cgi?id=19900">19900</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>string::operator==(const char *) unnecessarily computes rhs length, then doesn't take advantage of it
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libc++
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>3.4
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>Macintosh
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>All Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>corydoras@ridiculousfish.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu, mclow.lists@gmail.com
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>I noticed that my code was spending an inordinate amount of time in
std::string::operator!=(const char *). I dug and found that the implementation
is quite suboptimal, always traversing the rhs at least once. This bug tracks
optimizing it.

The std::string::operator== that takes a C string is defined like so:

    operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
           const _CharT* __rhs) _NOEXCEPT
    {
        return __lhs.compare(__rhs) == 0;
    }

where the eventual compare function is:

    template <class _CharT, class _Traits, class _Allocator>
    int
    basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s)
const _NOEXCEPT
    {
        _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr");
        return compare(0, npos, __s, traits_type::length(__s));
    }


There's two ways in which this is suboptimal:

1. The call to type_traits::length is a strlen, and may be expensive if the rhs
is long. It is also unnecessary; i.e. it should do the moral equivalent of
strcmp instead of strlen + memcmp.

2. Once we've incurred the expense of computing the length, if the lengths are
different, the strings must not be equal. But it does not use that information
until after the full character-by-character comparison!

I poked in the standard for operator== and found "Notes: Uses
traits::length()," so I worry that the standard requires this absurd
implementation. But here's hoping we can make it better.</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>