mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-30 07:14:09 +08:00
re PR libstdc++/13341 (ctype<wchar_t>::do_narrow(wchar_t, char) is slow)
2003-12-12 Paolo Carlini <pcarlini@suse.de> Benjamin Kosnik <bkoz@redhat.com> PR libstdc++/13341 * include/bits/locale_facets.h (ctype<wchar_t>): Declare _M_initialize_ctype() and _M_narrow_ok, _M_narrow and _M_widen. * src/ctype.cc (ctype<wchar_t>::ctype(size_t), ctype<wchar_t>::ctype(__c_locale, size_t)): Use _M_initialize_ctype to fill _M_narrow and _M_widen. (ctype_byname<wchar_t>::ctype_byname(const char*, size_t)): Likewise. * config/locale/generic/ctype_members.cc (do_narrow, do_widen) Use _M_narrow and _M_widen when possible, instead of calling wctob and btowc, respectively. (_M_initialize_ctype): Define, it fills at construction time _M_narrow and _M_widen. * config/locale/gnu/ctype_members.cc: Likewise. * testsuite/performance/narrow_widen_wchar_t.cc: New. Co-Authored-By: Benjamin Kosnik <bkoz@redhat.com> From-SVN: r74580
This commit is contained in:
parent
e00853fd90
commit
e3c0c0989b
@ -1,3 +1,22 @@
|
||||
2003-12-12 Paolo Carlini <pcarlini@suse.de>
|
||||
Benjamin Kosnik <bkoz@redhat.com>
|
||||
|
||||
PR libstdc++/13341
|
||||
* include/bits/locale_facets.h (ctype<wchar_t>): Declare
|
||||
_M_initialize_ctype() and _M_narrow_ok, _M_narrow and _M_widen.
|
||||
* src/ctype.cc (ctype<wchar_t>::ctype(size_t),
|
||||
ctype<wchar_t>::ctype(__c_locale, size_t)): Use
|
||||
_M_initialize_ctype to fill _M_narrow and _M_widen.
|
||||
(ctype_byname<wchar_t>::ctype_byname(const char*, size_t)):
|
||||
Likewise.
|
||||
* config/locale/generic/ctype_members.cc (do_narrow, do_widen)
|
||||
Use _M_narrow and _M_widen when possible, instead of calling
|
||||
wctob and btowc, respectively.
|
||||
(_M_initialize_ctype): Define, it fills at construction time
|
||||
_M_narrow and _M_widen.
|
||||
* config/locale/gnu/ctype_members.cc: Likewise.
|
||||
* testsuite/performance/narrow_widen_wchar_t.cc: New.
|
||||
|
||||
2003-12-12 Jonathan Wakely <redi@gcc.gnu.org>
|
||||
|
||||
* docs/html/faq/index.txt: Regenerate after adding <link> tags.
|
||||
|
@ -185,7 +185,12 @@ namespace std
|
||||
wchar_t
|
||||
ctype<wchar_t>::
|
||||
do_widen(char __c) const
|
||||
{ return btowc(static_cast<unsigned char>(__c)); }
|
||||
{
|
||||
const unsigned char __uc = static_cast<unsigned char>(__c);
|
||||
if (__uc < 128)
|
||||
return _M_widen[__uc];
|
||||
return btowc(__uc);
|
||||
}
|
||||
|
||||
const char*
|
||||
ctype<wchar_t>::
|
||||
@ -193,7 +198,11 @@ namespace std
|
||||
{
|
||||
while (__lo < __hi)
|
||||
{
|
||||
*__dest = btowc(static_cast<unsigned char>(*__lo));
|
||||
const unsigned char __uc = static_cast<unsigned char>(*__lo);
|
||||
if (__uc < 128)
|
||||
*__dest = _M_widen[__uc];
|
||||
else
|
||||
*__dest = btowc(__uc);
|
||||
++__lo;
|
||||
++__dest;
|
||||
}
|
||||
@ -204,7 +213,9 @@ namespace std
|
||||
ctype<wchar_t>::
|
||||
do_narrow(wchar_t __wc, char __dfault) const
|
||||
{
|
||||
int __c = wctob(__wc);
|
||||
if (__wc >= 0 && __wc < 128 && _M_narrow_ok)
|
||||
return _M_narrow[__wc];
|
||||
const int __c = wctob(__wc);
|
||||
return (__c == EOF ? __dfault : static_cast<char>(__c));
|
||||
}
|
||||
|
||||
@ -213,14 +224,48 @@ namespace std
|
||||
do_narrow(const wchar_t* __lo, const wchar_t* __hi, char __dfault,
|
||||
char* __dest) const
|
||||
{
|
||||
while (__lo < __hi)
|
||||
{
|
||||
int __c = wctob(*__lo);
|
||||
*__dest = (__c == EOF ? __dfault : static_cast<char>(__c));
|
||||
++__lo;
|
||||
++__dest;
|
||||
}
|
||||
if (_M_narrow_ok)
|
||||
while (__lo < __hi)
|
||||
{
|
||||
if (*__lo >= 0 && *__lo < 128)
|
||||
*__dest = _M_narrow[*__lo];
|
||||
else
|
||||
{
|
||||
const int __c = wctob(*__lo);
|
||||
*__dest = (__c == EOF ? __dfault : static_cast<char>(__c));
|
||||
}
|
||||
++__lo;
|
||||
++__dest;
|
||||
}
|
||||
else
|
||||
while (__lo < __hi)
|
||||
{
|
||||
const int __c = wctob(*__lo);
|
||||
*__dest = (__c == EOF ? __dfault : static_cast<char>(__c));
|
||||
++__lo;
|
||||
++__dest;
|
||||
}
|
||||
return __hi;
|
||||
}
|
||||
|
||||
void
|
||||
ctype<wchar_t>::_M_initialize_ctype()
|
||||
{
|
||||
wint_t __i;
|
||||
for (__i = 0; __i < 128; ++__i)
|
||||
{
|
||||
const int __c = wctob(__i);
|
||||
if (__c == EOF)
|
||||
break;
|
||||
else
|
||||
_M_narrow[__i] = static_cast<char>(__c);
|
||||
}
|
||||
if (__i == 128)
|
||||
_M_narrow_ok = true;
|
||||
else
|
||||
_M_narrow_ok = false;
|
||||
for (int __i = 0; __i < 128; ++__i)
|
||||
_M_widen[__i] = btowc(__i);
|
||||
}
|
||||
#endif // _GLIBCXX_USE_WCHAR_T
|
||||
}
|
||||
|
@ -192,14 +192,17 @@ namespace std
|
||||
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
|
||||
wchar_t __ret = btowc(static_cast<unsigned char>(__c));
|
||||
const wchar_t __wc = btowc(__uc);
|
||||
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
|
||||
__uselocale(__old);
|
||||
#endif
|
||||
return __ret;
|
||||
return __wc;
|
||||
}
|
||||
|
||||
const char*
|
||||
@ -211,7 +214,11 @@ namespace std
|
||||
#endif
|
||||
while (__lo < __hi)
|
||||
{
|
||||
*__dest = btowc(static_cast<unsigned char>(*__lo));
|
||||
const unsigned char __uc = static_cast<unsigned char>(*__lo);
|
||||
if (__uc < 128)
|
||||
*__dest = _M_widen[__uc];
|
||||
else
|
||||
*__dest = btowc(__uc);
|
||||
++__lo;
|
||||
++__dest;
|
||||
}
|
||||
@ -225,10 +232,12 @@ namespace std
|
||||
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)
|
||||
__c_locale __old = __uselocale(_M_c_locale_ctype);
|
||||
#endif
|
||||
int __c = wctob(__wc);
|
||||
const int __c = wctob(__wc);
|
||||
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
|
||||
__uselocale(__old);
|
||||
#endif
|
||||
@ -243,17 +252,57 @@ namespace std
|
||||
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
|
||||
__c_locale __old = __uselocale(_M_c_locale_ctype);
|
||||
#endif
|
||||
while (__lo < __hi)
|
||||
{
|
||||
int __c = wctob(*__lo);
|
||||
*__dest = (__c == EOF ? __dfault : static_cast<char>(__c));
|
||||
++__lo;
|
||||
++__dest;
|
||||
}
|
||||
if (_M_narrow_ok)
|
||||
while (__lo < __hi)
|
||||
{
|
||||
if (*__lo >= 0 && *__lo < 128)
|
||||
*__dest = _M_narrow[*__lo];
|
||||
else
|
||||
{
|
||||
const int __c = wctob(*__lo);
|
||||
*__dest = (__c == EOF ? __dfault : static_cast<char>(__c));
|
||||
}
|
||||
++__lo;
|
||||
++__dest;
|
||||
}
|
||||
else
|
||||
while (__lo < __hi)
|
||||
{
|
||||
const int __c = wctob(*__lo);
|
||||
*__dest = (__c == EOF ? __dfault : static_cast<char>(__c));
|
||||
++__lo;
|
||||
++__dest;
|
||||
}
|
||||
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
|
||||
__uselocale(__old);
|
||||
#endif
|
||||
return __hi;
|
||||
}
|
||||
|
||||
void
|
||||
ctype<wchar_t>::_M_initialize_ctype()
|
||||
{
|
||||
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
|
||||
__c_locale __old = __uselocale(_M_c_locale_ctype);
|
||||
#endif
|
||||
wint_t __i;
|
||||
for (__i = 0; __i < 128; ++__i)
|
||||
{
|
||||
const int __c = wctob(__i);
|
||||
if (__c == EOF)
|
||||
break;
|
||||
else
|
||||
_M_narrow[__i] = static_cast<char>(__c);
|
||||
}
|
||||
if (__i == 128)
|
||||
_M_narrow_ok = true;
|
||||
else
|
||||
_M_narrow_ok = false;
|
||||
for (int __i = 0; __i < 128; ++__i)
|
||||
_M_widen[__i] = btowc(__i);
|
||||
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
|
||||
__uselocale(__old);
|
||||
#endif
|
||||
}
|
||||
#endif // _GLIBCXX_USE_WCHAR_T
|
||||
}
|
||||
|
@ -446,6 +446,11 @@ namespace std
|
||||
protected:
|
||||
__c_locale _M_c_locale_ctype;
|
||||
|
||||
// Pre-computed narrowed and widened chars in the range 0-127.
|
||||
bool _M_narrow_ok;
|
||||
char _M_narrow[128];
|
||||
wint_t _M_widen[128];
|
||||
|
||||
public:
|
||||
// Data Members:
|
||||
static locale::id id;
|
||||
@ -500,6 +505,10 @@ namespace std
|
||||
virtual const char_type*
|
||||
do_narrow(const char_type* __lo, const char_type* __hi,
|
||||
char __dfault, char* __dest) const;
|
||||
|
||||
// For use at construction time only.
|
||||
void
|
||||
_M_initialize_ctype();
|
||||
};
|
||||
|
||||
template<>
|
||||
|
@ -87,11 +87,17 @@ namespace std
|
||||
#ifdef _GLIBCXX_USE_WCHAR_T
|
||||
ctype<wchar_t>::ctype(size_t __refs)
|
||||
: __ctype_abstract_base<wchar_t>(__refs)
|
||||
{ _M_c_locale_ctype = _S_get_c_locale(); }
|
||||
{
|
||||
_M_c_locale_ctype = _S_get_c_locale();
|
||||
_M_initialize_ctype();
|
||||
}
|
||||
|
||||
ctype<wchar_t>::ctype(__c_locale __cloc, size_t __refs)
|
||||
: __ctype_abstract_base<wchar_t>(__refs)
|
||||
{ _M_c_locale_ctype = _S_clone_c_locale(__cloc); }
|
||||
{
|
||||
_M_c_locale_ctype = _S_clone_c_locale(__cloc);
|
||||
_M_initialize_ctype();
|
||||
}
|
||||
|
||||
ctype<wchar_t>::~ctype()
|
||||
{ _S_destroy_c_locale(_M_c_locale_ctype); }
|
||||
@ -103,7 +109,8 @@ namespace std
|
||||
if (std::strcmp(__s, "C") != 0 && std::strcmp(__s, "POSIX") != 0)
|
||||
{
|
||||
_S_destroy_c_locale(_M_c_locale_ctype);
|
||||
_S_create_c_locale(_M_c_locale_ctype, __s);
|
||||
_S_create_c_locale(_M_c_locale_ctype, __s);
|
||||
_M_initialize_ctype();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
59
libstdc++-v3/testsuite/performance/narrow_widen_wchar_t.cc
Normal file
59
libstdc++-v3/testsuite/performance/narrow_widen_wchar_t.cc
Normal file
@ -0,0 +1,59 @@
|
||||
// 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 <testsuite_performance.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace std;
|
||||
using namespace __gnu_test;
|
||||
|
||||
time_counter time;
|
||||
resource_counter resource;
|
||||
const long iters = 200000000;
|
||||
|
||||
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)
|
||||
ct.narrow(i % 128, '*');
|
||||
stop_counters(time, resource);
|
||||
report_performance(__FILE__, "narrow", time, resource);
|
||||
clear_counters(time, resource);
|
||||
|
||||
// widen
|
||||
start_counters(time, resource);
|
||||
for (long i = 0; i < iters; ++i)
|
||||
ct.widen(i % 128);
|
||||
stop_counters(time, resource);
|
||||
report_performance(__FILE__, "widen", time, resource);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user