diff options
author | Paolo Carlini <pcarlini@suse.de> | 2003-12-16 11:00:52 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2003-12-16 11:00:52 +0000 |
commit | 9a1349b9209349989a0b776fe0683c21b197776e (patch) | |
tree | a5de1c73e744245f5ae1f7ee38776eaa37b059eb /libstdc++-v3 | |
parent | a0c68737027348fb9ae1ff4a5a33a10d269962bb (diff) | |
download | gcc-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
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/ChangeLog | 17 | ||||
-rw-r--r-- | libstdc++-v3/config/locale/generic/ctype_members.cc | 24 | ||||
-rw-r--r-- | libstdc++-v3/config/locale/gnu/ctype_members.cc | 28 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/locale_facets.h | 42 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/performance/is_wchar_t.cc | 87 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/performance/narrow_widen_char.cc | 2 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/performance/narrow_widen_wchar_t.cc | 2 |
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; |