aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <pcarlini@suse.de>2003-12-16 11:00:52 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2003-12-16 11:00:52 +0000
commit9a1349b9209349989a0b776fe0683c21b197776e (patch)
treea5de1c73e744245f5ae1f7ee38776eaa37b059eb
parenta0c68737027348fb9ae1ff4a5a33a10d269962bb (diff)
downloadgcc-9a1349b9209349989a0b776fe0683c21b197776e.zip
gcc-9a1349b9209349989a0b776fe0683c21b197776e.tar.gz
gcc-9a1349b9209349989a0b776fe0683c21b197776e.tar.bz2
re PR libstdc++/11723 (ctype<wchar_t>::do_is(mask, wchar_t) is slow)
2003-12-16 Paolo Carlini <pcarlini@suse.de> PR libstdc++/11723 * include/bits/locale_facets.h: Add _M_bit and _M_wmask, used to speed up the computation of ctype::do_is. * config/locale/generic/ctype_members.cc (_M_initialize_ctype): Fill _M_bit and _M_wmask. (ctype::do_is): Use _M_bit and _M_wmask. * config/locale/gnu/ctype_members.cc: Likewise. * testsuite/performance/is_wchar_t.cc: New. * testsuite/performance/narrow_widen_wchar_t.cc: Tweak string literal (incorrect citation ;) * include/bits/locale_facets.h: Minor tweaks, const correctness, unsigned -> size_t. From-SVN: r74686
-rw-r--r--libstdc++-v3/ChangeLog17
-rw-r--r--libstdc++-v3/config/locale/generic/ctype_members.cc24
-rw-r--r--libstdc++-v3/config/locale/gnu/ctype_members.cc28
-rw-r--r--libstdc++-v3/include/bits/locale_facets.h42
-rw-r--r--libstdc++-v3/testsuite/performance/is_wchar_t.cc87
-rw-r--r--libstdc++-v3/testsuite/performance/narrow_widen_char.cc2
-rw-r--r--libstdc++-v3/testsuite/performance/narrow_widen_wchar_t.cc2
7 files changed, 157 insertions, 45 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 60a7195..595922f 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,20 @@
+2003-12-16 Paolo Carlini <pcarlini@suse.de>
+
+ PR libstdc++/11723
+ * include/bits/locale_facets.h: Add _M_bit and _M_wmask,
+ used to speed up the computation of ctype::do_is.
+ * config/locale/generic/ctype_members.cc
+ (_M_initialize_ctype): Fill _M_bit and _M_wmask.
+ (ctype::do_is): Use _M_bit and _M_wmask.
+ * config/locale/gnu/ctype_members.cc: Likewise.
+ * testsuite/performance/is_wchar_t.cc: New.
+
+ * testsuite/performance/narrow_widen_wchar_t.cc: Tweak
+ string literal (incorrect citation ;)
+
+ * include/bits/locale_facets.h: Minor tweaks, const
+ correctness, unsigned -> size_t.
+
2003-12-16 Jerry Quinn <jlquinn@optonline.net>
* include/bits/locale_facets.h (widen, narrow): Uncomment the
diff --git a/libstdc++-v3/config/locale/generic/ctype_members.cc b/libstdc++-v3/config/locale/generic/ctype_members.cc
index e94d447..3166675 100644
--- a/libstdc++-v3/config/locale/generic/ctype_members.cc
+++ b/libstdc++-v3/config/locale/generic/ctype_members.cc
@@ -135,11 +135,12 @@ namespace std
// encoding of the various categories in /usr/include/ctype.h.
const size_t __bitmasksize = 15;
for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur)
- {
- const mask __bit = static_cast<mask>(1 << __bitcur);
- if (__m & __bit)
- __ret |= iswctype(__c, _M_convert_to_wmask(__bit));
- }
+ if (__m & _M_bit[__bitcur]
+ && iswctype(__c, _M_wmask[__bitcur]))
+ {
+ __ret = true;
+ break;
+ }
return __ret;
}
@@ -154,11 +155,8 @@ namespace std
const size_t __bitmasksize = 15;
mask __m = 0;
for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur)
- {
- const mask __bit = static_cast<mask>(1 << __bitcur);
- if (iswctype(*__lo, _M_convert_to_wmask(__bit)))
- __m |= __bit;
- }
+ if (iswctype(*__lo, _M_wmask[__bitcur]))
+ __m |= _M_bit[__bitcur];
*__vec = __m;
}
return __hi;
@@ -258,6 +256,12 @@ namespace std
for (size_t __i = 0;
__i < sizeof(_M_widen) / sizeof(wint_t); ++__i)
_M_widen[__i] = btowc(__i);
+
+ for (size_t __i = 0; __i <= 15; ++__i)
+ {
+ _M_bit[__i] = static_cast<mask>(1 << __i);
+ _M_wmask[__i] = _M_convert_to_wmask(_M_bit[__i]);
+ }
}
#endif // _GLIBCXX_USE_WCHAR_T
}
diff --git a/libstdc++-v3/config/locale/gnu/ctype_members.cc b/libstdc++-v3/config/locale/gnu/ctype_members.cc
index 998737b..db01d2d 100644
--- a/libstdc++-v3/config/locale/gnu/ctype_members.cc
+++ b/libstdc++-v3/config/locale/gnu/ctype_members.cc
@@ -139,12 +139,12 @@ namespace std
bool __ret = false;
const size_t __bitmasksize = 11;
for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur)
- {
- const mask __bit = static_cast<mask>(_ISbit(__bitcur));
- if (__m & __bit)
- __ret |= __iswctype_l(__c, _M_convert_to_wmask(__bit),
- _M_c_locale_ctype);
- }
+ if (__m & _M_bit[__bitcur]
+ && __iswctype_l(__c, _M_wmask[__bitcur], _M_c_locale_ctype))
+ {
+ __ret = true;
+ break;
+ }
return __ret;
}
@@ -152,19 +152,15 @@ namespace std
ctype<wchar_t>::
do_is(const wchar_t* __lo, const wchar_t* __hi, mask* __vec) const
{
- for (;__lo < __hi; ++__vec, ++__lo)
+ for (; __lo < __hi; ++__vec, ++__lo)
{
// Highest bitmask in ctype_base == 10, but extra in "C"
// library for blank.
const size_t __bitmasksize = 11;
mask __m = 0;
for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur)
- {
- const mask __bit = static_cast<mask>(_ISbit(__bitcur));
- if (__iswctype_l(*__lo, _M_convert_to_wmask(__bit),
- _M_c_locale_ctype))
- __m |= __bit;
- }
+ if (__iswctype_l(*__lo, _M_wmask[__bitcur], _M_c_locale_ctype))
+ __m |= _M_bit[__bitcur];
*__vec = __m;
}
return __hi;
@@ -279,6 +275,12 @@ namespace std
for (size_t __i = 0;
__i < sizeof(_M_widen) / sizeof(wint_t); ++__i)
_M_widen[__i] = btowc(__i);
+
+ for (size_t __i = 0; __i <= 11; ++__i)
+ {
+ _M_bit[__i] = static_cast<mask>(_ISbit(__i));
+ _M_wmask[__i] = _M_convert_to_wmask(_M_bit[__i]);
+ }
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
__uselocale(__old);
#endif
diff --git a/libstdc++-v3/include/bits/locale_facets.h b/libstdc++-v3/include/bits/locale_facets.h
index 9dfe9bb..055dc1f 100644
--- a/libstdc++-v3/include/bits/locale_facets.h
+++ b/libstdc++-v3/include/bits/locale_facets.h
@@ -247,7 +247,7 @@ namespace std
virtual const char_type*
do_narrow(const char_type* __lo, const char_type* __hi,
- char __dfault, char* __dest) const = 0;
+ char __dfault, char* __dest) const = 0;
};
// NB: Generic, mostly useless implementation.
@@ -394,16 +394,16 @@ namespace std
narrow(char_type __c, char __dfault) const
{
if (_M_narrow[__c]) return _M_narrow[__c];
- char __t = do_narrow(__c, __dfault);
+ const char __t = do_narrow(__c, __dfault);
if (__t != __dfault) _M_narrow[__c] = __t;
return __t;
}
const char_type*
narrow(const char_type* __lo, const char_type* __hi,
- char __dfault, char *__to) const
+ char __dfault, char *__to) const
{
- if (__builtin_expect(_M_narrow_ok==1,true))
+ if (__builtin_expect(_M_narrow_ok == 1,true))
{
memcpy(__to, __lo, __hi - __lo);
return __hi;
@@ -464,13 +464,13 @@ namespace std
void _M_widen_init() const
{
char __tmp[sizeof(_M_widen)];
- for (unsigned __i = 0; __i < sizeof(_M_widen); ++__i)
+ for (size_t __i = 0; __i < sizeof(_M_widen); ++__i)
__tmp[__i] = __i;
do_widen(__tmp, __tmp + sizeof(__tmp), _M_widen);
_M_widen_ok = 1;
// Set _M_widen_ok to 2 if memcpy can't be used.
- for (unsigned __i = 0; __i < sizeof(_M_widen); ++__i)
+ for (size_t __i = 0; __i < sizeof(_M_widen); ++__i)
if (__tmp[__i] != _M_widen[__i])
{
_M_widen_ok = 2;
@@ -484,26 +484,24 @@ namespace std
void _M_narrow_init() const
{
char __tmp[sizeof(_M_narrow)];
- for (unsigned __i = 0; __i < sizeof(_M_narrow); ++__i)
+ for (size_t __i = 0; __i < sizeof(_M_narrow); ++__i)
__tmp[__i] = __i;
do_narrow(__tmp, __tmp + sizeof(__tmp), 0, _M_narrow);
// Check if any default values were created. Do this by
// renarrowing with a different default value and comparing.
bool __consecutive = true;
- for (unsigned __i = 0; __i < sizeof(_M_narrow); ++__i)
- {
- char __c[1];
- if (!_M_narrow[__i])
- {
- do_narrow(__tmp + __i, __tmp + __i + 1, 1, __c);
- if (__c[0] == 1)
- {
- __consecutive = false;
- break;
- }
- }
- }
+ for (size_t __i = 0; __i < sizeof(_M_narrow); ++__i)
+ if (!_M_narrow[__i])
+ {
+ char __c;
+ do_narrow(__tmp + __i, __tmp + __i + 1, 1, &__c);
+ if (__c == 1)
+ {
+ __consecutive = false;
+ break;
+ }
+ }
_M_narrow_ok = __consecutive ? 1 : 2;
}
};
@@ -530,6 +528,10 @@ namespace std
char _M_narrow[128];
wint_t _M_widen[1 + static_cast<unsigned char>(-1)];
+ // Pre-computed elements for do_is.
+ mask _M_bit[16];
+ __wmask_type _M_wmask[16];
+
public:
// Data Members:
static locale::id id;
diff --git a/libstdc++-v3/testsuite/performance/is_wchar_t.cc b/libstdc++-v3/testsuite/performance/is_wchar_t.cc
new file mode 100644
index 0000000..e35edd0
--- /dev/null
+++ b/libstdc++-v3/testsuite/performance/is_wchar_t.cc
@@ -0,0 +1,87 @@
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#include <locale>
+#include <cwctype>
+#include <cstddef>
+#include <testsuite_performance.h>
+
+int main()
+{
+ using namespace std;
+ using namespace __gnu_test;
+
+ time_counter time;
+ resource_counter resource;
+ const wchar_t str[] =
+ L"Is this the real life?\n"
+ L"Is this just fantasy?\n"
+ L"Caught in a landslide\n"
+ L"No escape from reality\n"
+ L"Open your eyes\n"
+ L"Look up to the skies and see\n"
+ L"I'm just a poor boy\n"
+ L"I need no sympathy\n"
+ L"Because I'm easy come, easy go\n"
+ L"Little high, little low"
+ L"Anyway the wind blows\n"
+ L"Doesn't really matter to me\n"
+ L"To me\n"
+ L" -- Queen\n";
+ const size_t len = sizeof(str) / sizeof(str[0]) - 1;
+
+ locale loc;
+ const ctype<wchar_t>& ct = use_facet<ctype<wchar_t> >(loc);
+
+ // C
+ wctype_t w = wctype("space");
+ start_counters(time, resource);
+ for (int j = 0; j < 200000; ++j)
+ {
+ for (size_t i = 0; i < len; ++i)
+ {
+ iswctype(str[i], w);
+ }
+ }
+ stop_counters(time, resource);
+ report_performance(__FILE__, "C", time, resource);
+ clear_counters(time, resource);
+
+ // C++
+ start_counters(time, resource);
+ for (int j = 0; j < 200000; ++j)
+ {
+ for (size_t i = 0; i < len; ++i)
+ {
+ ct.is(ctype_base::space, str[i]);
+ }
+ }
+ stop_counters(time, resource);
+ report_performance(__FILE__, "C++", time, resource);
+
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/performance/narrow_widen_char.cc b/libstdc++-v3/testsuite/performance/narrow_widen_char.cc
index d4dd658..d6376b9 100644
--- a/libstdc++-v3/testsuite/performance/narrow_widen_char.cc
+++ b/libstdc++-v3/testsuite/performance/narrow_widen_char.cc
@@ -37,7 +37,7 @@ int main()
resource_counter resource;
const long iters = 200000000;
char bufin[] = "This was an attempt to bypass string construction just for test.";
- char bufout[sizeof(bufin) + 1];
+ char bufout[sizeof(bufin)];
locale loc;
const ctype<char>& ct = use_facet<ctype<char> >(loc);
diff --git a/libstdc++-v3/testsuite/performance/narrow_widen_wchar_t.cc b/libstdc++-v3/testsuite/performance/narrow_widen_wchar_t.cc
index 053f807..da3e4f2 100644
--- a/libstdc++-v3/testsuite/performance/narrow_widen_wchar_t.cc
+++ b/libstdc++-v3/testsuite/performance/narrow_widen_wchar_t.cc
@@ -35,7 +35,7 @@ int main()
time_counter time;
resource_counter resource;
- wchar_t bufwc[] = L"M'innamoravo di tutto (Fabrizio De Andre')";
+ wchar_t bufwc[] = L"Mi innamoravo di tutto (Fabrizio De Andre')";
char bufc[sizeof(bufwc) / sizeof(wchar_t)];
locale loc;