Optimal basic_string<>::append

Ryszard Kabatek Ryszard.Kabatek@softax.pl
Mon Dec 17 04:24:00 GMT 2001


The basic_string<>::append member functions
are implemented in the way:

...
if (__len > this->capacity())
        this->reserve(__len);
 return _M_replace_safe(...)

Example:
    append(const basic_string& __str)
    {
      // Iff appending itself, string needs to pre-reserve the
      // correct size so that _M_mutate does not clobber the
      // iterators formed here.
      size_type __size = __str.size();
      size_type __len = __size + this->size();
      if (__len > this->capacity())
        this->reserve(__len);
      return _M_replace_safe(_M_iend(), _M_iend(), __str._M_ibegin(),
                             __str._M_iend());
    }


It is unnecessary and it slows down the appending.
Now since _M_mutate (called by _M_replace_safe but not by reserve)
provides a good reallocation strategy, append should call
the reserve member function only if appending the string itself. 

So the append member function can be implemented in the way:

    append(const basic_string& __str)
    {
      // Iff appending itself, string needs to pre-reserve the
      // correct size so that _M_mutate does not clobber the
      // iterators formed here.
      if (this == &__str)
      {
         size_type __size = __str.size();
         size_type __len = __size + this->size();
         if (__len > this->capacity())
           this->reserve(__len);
      }
      return _M_replace_safe(_M_iend(), _M_iend(), __str._M_ibegin(),
                             __str._M_iend());
    }

Now append has benefit from the good reallocation strategy of _M_mutate.
I sent a patch regarding that problem in August.

Regards
-- 
Ryszard Kabatek

Tel. (Softax) +48 (22) 517 38 31
Tel. kom. (Softax) +48 (606) 609 363



More information about the Libstdc++ mailing list