This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: [Patch] Fix libstdc++/13341 (speed-up <wchar_t>::do_narrow/widen)
Benjamin Kosnik wrote:
1- Construction time doubled.
2- Memory usage doubled.
...both of these are one time hits. I think this is ok, given the
context (initialization).
Ok. The below are the corresponding changes: indeed, do_widen becomes
really minimal and
even faster. Good.
Tested x86-linux, gnu/generic.
Will wait 'til monday.
Paolo.
P.S. Perhaps it's obvious for you, sorry, but I mention here that
wctob(i) returns EOF
for all i : i > 127, already in the C locale.
//////////
2003-12-13 Paolo Carlini <pcarlini@suse.de>
* include/bits/locale_facets.h (_M_widen): Reserve space
for all the possible widened chars.
* config/locale/generic/ctype_members.cc (_M_initialize_ctype):
Compute at construction time all the possible widened chars.
(do_widen): Tweak, simplify.
* config/locale/gnu/ctype_members.cc: Likewise.
* testsuite/performance/narrow_widen_wchar_t.cc: Add tests
for the array versions.
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-12 20:44:17.000000000 +0100
+++ libstdc++-v3/config/locale/generic/ctype_members.cc 2003-12-13 17:30:33.000000000 +0100
@@ -185,12 +185,7 @@
wchar_t
ctype<wchar_t>::
do_widen(char __c) const
- {
- const unsigned char __uc = static_cast<unsigned char>(__c);
- if (__uc < 128)
- return _M_widen[__uc];
- return btowc(__uc);
- }
+ { return _M_widen[static_cast<unsigned char>(__c)]; }
const char*
ctype<wchar_t>::
@@ -198,11 +193,7 @@
{
while (__lo < __hi)
{
- const unsigned char __uc = static_cast<unsigned char>(*__lo);
- if (__uc < 128)
- *__dest = _M_widen[__uc];
- else
- *__dest = btowc(__uc);
+ *__dest = _M_widen[static_cast<unsigned char>(*__lo)];
++__lo;
++__dest;
}
@@ -264,7 +255,8 @@
_M_narrow_ok = true;
else
_M_narrow_ok = false;
- for (int __i = 0; __i < 128; ++__i)
+ for (size_t __i = 0;
+ __i < sizeof(_M_widen) / sizeof(wint_t); ++__i)
_M_widen[__i] = btowc(__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-12 20:44:15.000000000 +0100
+++ libstdc++-v3/config/locale/gnu/ctype_members.cc 2003-12-13 17:25:21.000000000 +0100
@@ -191,47 +191,25 @@
wchar_t
ctype<wchar_t>::
do_widen(char __c) const
- {
- const unsigned char __uc = static_cast<unsigned char>(__c);
- if (__uc < 128)
- return _M_widen[__uc];
-#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
- __c_locale __old = __uselocale(_M_c_locale_ctype);
-#endif
- const wchar_t __wc = btowc(__uc);
-#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
- __uselocale(__old);
-#endif
- return __wc;
- }
+ { return _M_widen[static_cast<unsigned char>(__c)]; }
const char*
ctype<wchar_t>::
do_widen(const char* __lo, const char* __hi, wchar_t* __dest) const
{
-#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
- __c_locale __old = __uselocale(_M_c_locale_ctype);
-#endif
while (__lo < __hi)
{
- const unsigned char __uc = static_cast<unsigned char>(*__lo);
- if (__uc < 128)
- *__dest = _M_widen[__uc];
- else
- *__dest = btowc(__uc);
+ *__dest = _M_widen[static_cast<unsigned char>(*__lo)];
++__lo;
++__dest;
}
-#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
- __uselocale(__old);
-#endif
return __hi;
}
char
ctype<wchar_t>::
do_narrow(wchar_t __wc, char __dfault) const
- {
+ {
if (__wc >= 0 && __wc < 128 && _M_narrow_ok)
return _M_narrow[__wc];
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
@@ -298,7 +276,8 @@
_M_narrow_ok = true;
else
_M_narrow_ok = false;
- for (int __i = 0; __i < 128; ++__i)
+ for (size_t __i = 0;
+ __i < sizeof(_M_widen) / sizeof(wint_t); ++__i)
_M_widen[__i] = btowc(__i);
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
__uselocale(__old);
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-12 20:44:15.000000000 +0100
+++ libstdc++-v3/include/bits/locale_facets.h 2003-12-13 17:27:20.000000000 +0100
@@ -446,10 +446,10 @@
protected:
__c_locale _M_c_locale_ctype;
- // Pre-computed narrowed and widened chars in the range 0-127.
- bool _M_narrow_ok;
+ // Pre-computed narrowed and widened chars.
+ bool _M_narrow_ok;
char _M_narrow[128];
- wint_t _M_widen[128];
+ wint_t _M_widen[1 + static_cast<unsigned char>(-1)];
public:
// Data Members:
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-12 20:44:17.000000000 +0100
+++ libstdc++-v3/testsuite/performance/narrow_widen_wchar_t.cc 2003-12-13 17:26:06.000000000 +0100
@@ -35,25 +35,41 @@
time_counter time;
resource_counter resource;
- const long iters = 200000000;
+ wchar_t bufwc[] = L"M'innamoravo di tutto (Fabrizio De Andre')";
+ char bufc[sizeof(bufwc) / sizeof(wchar_t)];
locale loc;
const ctype<wchar_t>& ct = use_facet<ctype<wchar_t> >(loc);
// narrow
start_counters(time, resource);
- for (long i = 0; i < iters; ++i)
+ for (long i = 0; i < 200000000; ++i)
ct.narrow(i % 128, '*');
stop_counters(time, resource);
report_performance(__FILE__, "narrow", time, resource);
clear_counters(time, resource);
+ // narrow array
+ start_counters(time, resource);
+ for (long i = 0; i < 20000000; ++i)
+ ct.narrow(bufwc, bufwc + sizeof(bufwc) / sizeof(wchar_t), '*', bufc);
+ stop_counters(time, resource);
+ report_performance(__FILE__, "narrow array", time, resource);
+ clear_counters(time, resource);
+
// widen
start_counters(time, resource);
- for (long i = 0; i < iters; ++i)
+ for (long i = 0; i < 200000000; ++i)
ct.widen(i % 128);
stop_counters(time, resource);
report_performance(__FILE__, "widen", time, resource);
+ // widen array
+ start_counters(time, resource);
+ for (long i = 0; i < 20000000; ++i)
+ ct.widen(bufc, bufc + sizeof(bufc), bufwc);
+ stop_counters(time, resource);
+ report_performance(__FILE__, "widen array", time, resource);
+
return 0;
}