This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

[v3] Patch to _M_extract_int for excess operator*() calls...


Hi,

similarly to _M_extract_float. Tested x86/x86_64-linux, committed
to mainline.

(performance-wise, it's worth 3-5% for testcases reading integers,
both on x86 and x86_64)

Paolo.

/////////////
2004-11-02  Paolo Carlini  <pcarlini@suse.de>

	* include/bits/locale_facets.tcc (num_get<>::_M_extract_int):
	Evaluate *__beg the exact strict minimum number of times; likewise
	for __beg != __end; slightly simplify main parsing loop.

diff -urN libstdc++-v3-orig/include/bits/locale_facets.tcc libstdc++-v3/include/bits/locale_facets.tcc
--- libstdc++-v3-orig/include/bits/locale_facets.tcc	2004-10-31 18:47:29.000000000 +0100
+++ libstdc++-v3/include/bits/locale_facets.tcc	2004-11-02 11:35:44.000000000 +0100
@@ -301,10 +301,8 @@
 	    }
 	}
 
-      // True if a mantissa is found.
-      bool __found_mantissa = false;
-
       // Next, look for leading zeros.
+      bool __found_mantissa = false;
       while (!__testeof)
 	{
 	  if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep
@@ -452,6 +450,7 @@
 	const locale& __loc = __io._M_getloc();
 	const __cache_type* __lc = __uc(__loc);
 	const _CharT* __lit = __lc->_M_atoms_in;
+	char_type __c = char_type();
 
 	// NB: Iff __basefield == 0, __base can change based on contents.
 	const ios_base::fmtflags __basefield = __io.flags()
@@ -459,36 +458,38 @@
 	const bool __oct = __basefield == ios_base::oct;
 	int __base = __oct ? 8 : (__basefield == ios_base::hex ? 16 : 10);
 
-	// True if numeric digits are found.
-	bool __found_num = false;
+	// True if __beg becomes equal to __end.
+	bool __testeof = __beg == __end;
 
 	// First check for sign.
 	bool __negative = false;
-	if (__beg != __end)
+	if (!__testeof)
 	  {
-	    const char_type __c = *__beg;
+	    __c = *__beg;
 	    if (numeric_limits<_ValueT>::is_signed)
 	      __negative = __c == __lit[__num_base::_S_iminus];
 	    if ((__negative || __c == __lit[__num_base::_S_iplus])
 		&& !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
 		&& !(__c == __lc->_M_decimal_point))
-	      ++__beg;
+	      {
+		if (++__beg != __end)
+		  __c = *__beg;
+		else
+		  __testeof = true;
+	      }
 	  }
 
 	// Next, look for leading zeros and check required digits
 	// for base formats.
-	while (__beg != __end)
+	bool __found_num = false;
+	while (!__testeof)
 	  {
-	    const char_type __c = *__beg;
 	    if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep
 		|| __c == __lc->_M_decimal_point)
 	      break;
 	    else if (__c == __lit[__num_base::_S_izero] 
 		     && (!__found_num || __base == 10))
-	      {
-		__found_num = true;
-		++__beg;
-	      }
+	      __found_num = true;
 	    else if (__found_num)
 	      {
 		if (__c == __lit[__num_base::_S_ix] 
@@ -499,7 +500,10 @@
 		    if (__base == 16)
 		      {
 			__found_num = false;
-			++__beg;
+			if (++__beg != __end)
+			  __c = *__beg;
+			else
+			  __testeof = true;
 		      }
 		  }
 		else if (__basefield == 0)
@@ -508,6 +512,11 @@
 	      }
 	    else
 	      break;
+
+	    if (++__beg != __end)
+	      __c = *__beg;
+	    else
+	      __testeof = true;
 	  }
 
 	// At this point, base is determined. If not hex, only allow
@@ -522,15 +531,15 @@
 	int __sep_pos = 0;
 	bool __overflow = false;
 	_ValueT __result = 0;
+	const char_type* __q;
 	const char_type* __lit_zero = __lit + __num_base::_S_izero;
 	if (__negative)
 	  {
 	    const _ValueT __min = numeric_limits<_ValueT>::min() / __base;
-	    for (; __beg != __end; ++__beg)
+	    while (!__testeof)
 	      {
 		// According to 22.2.2.1.2, p8-9, first look for thousands_sep
 		// and decimal_point.
-		const char_type __c = *__beg;
 		if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
 		  {
 		    // NB: Thousands separator at the beginning of a string
@@ -548,39 +557,38 @@
 		  }
 		else if (__c == __lc->_M_decimal_point)
 		  break;
-		else
+		else if ((__q = __traits_type::find(__lit_zero, __len, __c)))
 		  {
-		    const char_type* __q = __traits_type::find(__lit_zero, 
-							       __len, __c);
-		    if (__q)
+		    int __digit = __q - __lit_zero;
+		    if (__digit > 15)
+		      __digit -= 6;
+		    if (__result < __min)
+		      __overflow = true;
+		    else
 		      {
-			int __digit = __q - __lit_zero;
-			if (__digit > 15)
-			  __digit -= 6;
-			if (__result < __min)
-			  __overflow = true;
-			else
-			  {
-			    const _ValueT __new_result = (__result * __base
-							  - __digit);
-			    __overflow |= __new_result > __result;
-			    __result = __new_result;
-			    ++__sep_pos;
-			    __found_num = true;
-			  }
+			const _ValueT __new_result = (__result * __base
+						      - __digit);
+			__overflow |= __new_result > __result;
+			__result = __new_result;
+			++__sep_pos;
+			__found_num = true;
 		      }
-		    else
-		      // Not a valid input item.
-		      break;
 		  }
+		else
+		  // Not a valid input item.
+		  break;
+
+		if (++__beg != __end)
+		  __c = *__beg;
+		else
+		  __testeof = true;
 	      }
 	  }
 	else
 	  {
 	    const _ValueT __max = numeric_limits<_ValueT>::max() / __base;
-	    for (; __beg != __end; ++__beg)
+	    while (!__testeof)
 	      {
-		const char_type __c = *__beg;
 		if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
 		  {
 		    if (__sep_pos)
@@ -596,30 +604,30 @@
 		  }
 		else if (__c == __lc->_M_decimal_point)
 		  break;
-		else
+		else if ((__q = __traits_type::find(__lit_zero, __len, __c)))
 		  {
-		    const char_type* __q = __traits_type::find(__lit_zero,
-							       __len, __c);    
-		    if (__q)
+		    int __digit = __q - __lit_zero;
+		    if (__digit > 15)
+		      __digit -= 6;
+		    if (__result > __max)
+		      __overflow = true;
+		    else
 		      {
-			int __digit = __q - __lit_zero;
-			if (__digit > 15)
-			  __digit -= 6;
-			if (__result > __max)
-			  __overflow = true;
-			else
-			  {
-			    const _ValueT __new_result = (__result * __base
-							  + __digit);
-			    __overflow |= __new_result < __result;
-			    __result = __new_result;
-			    ++__sep_pos;
-			    __found_num = true;
-			  }
+			const _ValueT __new_result = (__result * __base
+						      + __digit);
+			__overflow |= __new_result < __result;
+			__result = __new_result;
+			++__sep_pos;
+			__found_num = true;
 		      }
-		    else
-		      break;
 		  }
+		else
+		  break;
+
+		if (++__beg != __end)
+		  __c = *__beg;
+		else
+		  __testeof = true;
 	      }
 	  }
 
@@ -642,7 +650,7 @@
 	else
 	  __err |= ios_base::failbit;
 
-	if (__beg == __end)
+	if (__testeof)
 	  __err |= ios_base::eofbit;
 	return __beg;
       }

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