This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch] Tiny improvement for libstdc++/11602


Hi,

in order to really fix this performance problem drastic changes are
needed, most probably avoiding completely wcrtomb & co.

Anyway, the change below is really straighrforward and does a little
good. On my machine (P4-2400, -O2), for cspeed.cc, codecvt 100000:

3.4
---
15.590u 0.000s 0:15.87 98.2%    0+0k 0+0io 228pf+0w

3.4 + patch below
-----------------
9.600u 0.000s 0:09.76 98.3%     0+0k 0+0io 187pf+0w

Regression tested x86-linux. Barring objections, will commit soon.

Paolo.

//////////
2003-11-18  Paolo Carlini  <pcarlini@suse.de>

	* config/locale/gnu/codecvt_members.cc (do_out): If
	we can upper bound the total number of external chars
	to something smaller than __to_end - __to avoid the
	temporary buffer, the memcopy and simplify the loop.
diff -prN libstdc++-v3-orig/config/locale/gnu/codecvt_members.cc libstdc++-v3/config/locale/gnu/codecvt_members.cc
*** libstdc++-v3-orig/config/locale/gnu/codecvt_members.cc	Sat Jul  5 06:05:30 2003
--- libstdc++-v3/config/locale/gnu/codecvt_members.cc	Tue Nov 18 22:06:45 2003
*************** namespace std
*** 48,60 ****
  	 extern_type*& __to_next) const
    {
      result __ret = ok;
-     // The conversion must be done using a temporary destination buffer
-     // since it is not possible to pass the size of the buffer to wcrtomb
-     extern_type __buf[MB_LEN_MAX];
      // A temporary state must be used since the result of the last
      // conversion may be thrown away.
!     state_type __tmp_state(__state);
!     
  #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
      __c_locale __old = __uselocale(_M_c_locale_codecvt);
  #endif
--- 48,57 ----
  	 extern_type*& __to_next) const
    {
      result __ret = ok;
      // A temporary state must be used since the result of the last
      // conversion may be thrown away.
!     state_type __tmp_state(__state);   
! 
  #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
      __c_locale __old = __uselocale(_M_c_locale_codecvt);
  #endif
*************** namespace std
*** 62,85 ****
      // The conversion must be done by calling wcrtomb in a loop rather
      // than using wcsrtombs because wcsrtombs assumes that the input is
      // zero-terminated.
!     while (__from < __from_end && __to < __to_end)
        {
! 	size_t __conv = wcrtomb(__buf, *__from, &__tmp_state);
! 	if (__conv == static_cast<size_t>(-1))
  	  {
! 	    __ret = error;
! 	    break;
  	  }
- 	else if (__conv > static_cast<size_t>(__to_end - __to))
- 	  {
- 	    __ret = partial;
- 	    break;
- 	  }
- 
- 	memcpy(__to, __buf, __conv);
- 	__state = __tmp_state;
- 	__to += __conv;
- 	__from++;
        }
  
  #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
--- 59,104 ----
      // The conversion must be done by calling wcrtomb in a loop rather
      // than using wcsrtombs because wcsrtombs assumes that the input is
      // zero-terminated.
! 
!     // Either we can upper bound the total number of external characters to
!     // something smaller than __to_end - __to or the conversion must be done
!     // using a temporary destination buffer since it is not possible to
!     // pass the size of the buffer to wcrtomb
!     if (MB_CUR_MAX * (__from_end - __from) <= __to_end - __to)
!       while (__from < __from_end)
! 	{
! 	  const size_t __conv = wcrtomb(__to, *__from, &__tmp_state);
! 	  if (__conv == static_cast<size_t>(-1))
! 	    {
! 	      __ret = error;
! 	      break;
! 	    }
! 	  __state = __tmp_state;
! 	  __to += __conv;
! 	  __from++;
! 	}
!     else
        {
! 	extern_type __buf[MB_LEN_MAX];
! 	while (__from < __from_end && __to < __to_end)
  	  {
! 	    const size_t __conv = wcrtomb(__buf, *__from, &__tmp_state);
! 	    if (__conv == static_cast<size_t>(-1))
! 	      {
! 		__ret = error;
! 		break;
! 	      }
! 	    else if (__conv > static_cast<size_t>(__to_end - __to))
! 	      {
! 		__ret = partial;
! 		break;
! 	      }
! 	    
! 	    memcpy(__to, __buf, __conv);
! 	    __state = __tmp_state;
! 	    __to += __conv;
! 	    __from++;
  	  }
        }
  
  #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]