https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113704

            Bug ID: 113704
           Summary: std::locale::locale<Facet>(const locale&, Facet*) is
                    inefficient
           Product: gcc
           Version: 11.4.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: redi at gcc dot gnu.org
  Target Milestone: ---

template<typename _Facet>
    locale::
    locale(const locale& __other, _Facet* __f)
    {
      _M_impl = new _Impl(*__other._M_impl, 1);

      __try
        { _M_impl->_M_install_facet(&_Facet::id, __f); }
      __catch(...)
        {
          _M_impl->_M_remove_reference();
          __throw_exception_again;
        }
      delete [] _M_impl->_M_names[0];
      _M_impl->_M_names[0] = 0;   // Unnamed.
    }

This is very wasteful if the facet isn't already present in __other. First the
_Impl constructor allocates new copies of all the arrays in *__other._M_impl,
then _M_install_facets reallocates them with additional space for the new
facet.

We should check whether _Facet::id can be stored without reallocation. If it
can't, we should avoid allocating and copying all the arrays twice.

This matters for custom user facets which will always have a higher ID and
require reallocation.

Reply via email to