This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[Patch] (Almost) fix libstdc++/11723
- From: Paolo Carlini <pcarlini at suse dot de>
- To: libstdc++ <libstdc++ at gcc dot gnu dot org>
- Date: Tue, 16 Dec 2003 00:11:03 +0100
- Subject: [Patch] (Almost) fix libstdc++/11723
Hi,
this (almost) fixes the PR, in that we don't really achieve the
same speed of C, but a very good improvement with a minor cost
in terms of memory consumption and overhead at construction time.
I think it's ok for now. The approach is the same already used
for <wchar_t>::do_narrow/do_widen.
These are the numbers:
3.4
---
15.960u 0.020s 0:16.56 96.4% 0+0k 0+0io 175pf+0w
3.4 + patch
-----------
1.630u 0.000s 0:01.69 96.4% 0+0k 0+0io 175pf+0w
Tested x86-linux (gnu/generic). Will wait 'til tomorrow (italian
time) for comments...
Paolo.
////////////
2003-12-15 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 ;)
diff -urN libstdc++-v3-orig/config/locale/generic/ctype_members.cc libstdc++-v3/config/locale/generic/ctype_members.cc
--- libstdc++-v3-orig/config/locale/generic/ctype_members.cc 2003-12-15 17:56:41.000000000 +0100
+++ libstdc++-v3/config/locale/generic/ctype_members.cc 2003-12-15 22:40:45.000000000 +0100
@@ -135,11 +135,12 @@
// 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 @@
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 @@
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 -urN libstdc++-v3-orig/config/locale/gnu/ctype_members.cc libstdc++-v3/config/locale/gnu/ctype_members.cc
--- libstdc++-v3-orig/config/locale/gnu/ctype_members.cc 2003-12-15 17:56:41.000000000 +0100
+++ libstdc++-v3/config/locale/gnu/ctype_members.cc 2003-12-15 22:03:06.000000000 +0100
@@ -139,12 +139,12 @@
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 @@
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 @@
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 -urN libstdc++-v3-orig/include/bits/locale_facets.h libstdc++-v3/include/bits/locale_facets.h
--- libstdc++-v3-orig/include/bits/locale_facets.h 2003-12-15 17:56:40.000000000 +0100
+++ libstdc++-v3/include/bits/locale_facets.h 2003-12-15 23:00:12.000000000 +0100
@@ -451,6 +451,10 @@
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 -urN libstdc++-v3-orig/testsuite/performance/is_wchar_t.cc libstdc++-v3/testsuite/performance/is_wchar_t.cc
--- libstdc++-v3-orig/testsuite/performance/is_wchar_t.cc 1970-01-01 01:00:00.000000000 +0100
+++ libstdc++-v3/testsuite/performance/is_wchar_t.cc 2003-12-15 23:36:08.000000000 +0100
@@ -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 -urN libstdc++-v3-orig/testsuite/performance/narrow_widen_wchar_t.cc libstdc++-v3/testsuite/performance/narrow_widen_wchar_t.cc
--- libstdc++-v3-orig/testsuite/performance/narrow_widen_wchar_t.cc 2003-12-15 17:56:42.000000000 +0100
+++ libstdc++-v3/testsuite/performance/narrow_widen_wchar_t.cc 2003-12-15 23:28:51.000000000 +0100
@@ -35,7 +35,7 @@
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;