This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[Patch/RFA] Further speedup locale::operator==
- From: Paolo Carlini <pcarlini at suse dot de>
- To: libstdc++ <libstdc++ at gcc dot gnu dot org>
- Date: Thu, 29 Apr 2004 01:09:20 +0200
- Subject: [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;
}