This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch/RFA] Further speedup locale::operator==


Hi,

if I understand well the standard (i.e, 22.1.1.2) it is impossible for
a locale which has no name to acquire one. Indeed, our locale::_Impl::
_M_replace_categories is particularly enlightening about that.

Therefore _M_names[0] == "*" => for every i, _M_names[i] == "*".

This opens up the possibility to further speedup operator==, in
particular when the two locales are different:
- First, we avoid constructing __name only for testing __name != "*"
- Then, we compare directly pairs of corresponding _M_names (just
  /one/ comparison suffices for common "simple" (i.e., all the
  _M_names[i] equal) locales.

Indeed, for this:

 std::locale loc1("fr_FR");
 std::locale loc2("de_DE");
 for (int i = 0; i < 10000000; ++i)
   if (loc1 == loc2)
     abort();

current mainline
----------------
11.070u 0.000s 0:11.14 99.3%    0+0k 0+0io 252pf+0w

patched
-------
0.710u 0.000s 0:00.73 97.2%     0+0k 0+0io 250pf+0w

Regtested x86-linux (*)

If nobody finds a flaw in my reasoning I will commit this soon.

Paolo.

(*) The testsuite includes quite a few checks of the assumptions
above: see, f.i., 22_locale/locale/cons/2.cc.

////////////
2004-04-29  Paolo Carlini  <pcarlini@suse.de>

	* src/locale.cc (locale::operator==): Always avoid constructing
	locale::name(), compare directly pairs of _M_names.
diff -prN libstdc++-v3-orig/src/locale.cc libstdc++-v3/src/locale.cc
*** libstdc++-v3-orig/src/locale.cc	Thu Apr 15 10:27:29 2004
--- libstdc++-v3/src/locale.cc	Thu Apr 29 00:13:24 2004
*************** namespace std 
*** 70,84 ****
    bool
    locale::operator==(const locale& __rhs) const throw()
    {
!     bool __ret = false;
      if (_M_impl == __rhs._M_impl)
!       __ret = true;
      else
!       {
! 	const string __name = this->name();
! 	if (__name != "*" && __name == __rhs.name())
! 	  __ret = true;
!       }
      return __ret;
    }
  
--- 70,84 ----
    bool
    locale::operator==(const locale& __rhs) const throw()
    {
!     bool __ret = true;
      if (_M_impl == __rhs._M_impl)
!       ;
!     else if (!std::strcmp(_M_impl->_M_names[0], "*"))
!       __ret = false;
      else
!       for (size_t __i = 0; __ret && __i < _S_categories_size; ++__i)
! 	__ret = !std::strcmp(_M_impl->_M_names[__i],
! 			     __rhs._M_impl->_M_names[__i]);
      return __ret;
    }
  

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]