[PATCH] Improve istream extractors for floating point types

Jonathan Wakely jwakely@redhat.com
Fri Nov 17 21:31:00 GMT 2017


While working on I/O for std::decimal types (which I'm not going to
complete for gcc 8) I realised that std::num_get still uses the old
COW std::string for reading floating point types, which always
allocates memory.

With this patch (which is missing the fixes for the linker script to
give the new symbols the right version) we use the new std::string, so
if the value being read from the stream is shorter than 16 bytes we
don't need to allocate, and so can read much faster.

I think this is worth changing, but I need to do some more ABI
verification (and fix the linker script).


-------------- next part --------------
commit 19fd69a07bdd7fbb39fdf053756b1ae1c8457f5a
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Fri Nov 17 21:07:28 2017 +0000

    improve float parsing perf

diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc
index d7710e6bb32..f43b66c0761 100644
--- a/libstdc++-v3/include/bits/locale_facets.tcc
+++ b/libstdc++-v3/include/bits/locale_facets.tcc
@@ -207,8 +207,10 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL
       bool __found_dec = false;
       bool __found_sci = false;
       string __found_grouping;
+#if !_GLIBCXX_USE_CXX11_ABI
       if (__lc->_M_use_grouping)
 	__found_grouping.reserve(32);
+#endif
       const char_type* __lit_zero = __lit + __num_base::_S_izero;
 
       if (!__lc->_M_allocated)
@@ -465,8 +467,10 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL
 	// Extract.
 	typedef __gnu_cxx::__numeric_traits<_ValueT> __num_traits;
 	string __found_grouping;
+#if !_GLIBCXX_USE_CXX11_ABI
 	if (__lc->_M_use_grouping)
 	  __found_grouping.reserve(32);
+#endif
 	bool __testfail = false;
 	bool __testoverflow = false;
 	const __unsigned_type __max =
@@ -692,7 +696,9 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL
 	   ios_base::iostate& __err, float& __v) const
     {
       string __xtrc;
+#if !_GLIBCXX_USE_CXX11_ABI
       __xtrc.reserve(32);
+#endif
       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
       std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
       if (__beg == __end)
@@ -707,7 +713,9 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL
            ios_base::iostate& __err, double& __v) const
     {
       string __xtrc;
+#if !_GLIBCXX_USE_CXX11_ABI
       __xtrc.reserve(32);
+#endif
       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
       std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
       if (__beg == __end)
@@ -723,7 +731,9 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL
 	     ios_base::iostate& __err, double& __v) const
     {
       string __xtrc;
+#if !_GLIBCXX_USE_CXX11_ABI
       __xtrc.reserve(32);
+#endif
       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
       std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
       if (__beg == __end)
@@ -739,7 +749,9 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL
            ios_base::iostate& __err, long double& __v) const
     {
       string __xtrc;
+#if !_GLIBCXX_USE_CXX11_ABI
       __xtrc.reserve(32);
+#endif
       __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc);
       std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale());
       if (__beg == __end)
diff --git a/libstdc++-v3/src/c++11/locale-inst.cc b/libstdc++-v3/src/c++11/locale-inst.cc
index c1b8e8d2b6b..8022113867b 100644
--- a/libstdc++-v3/src/c++11/locale-inst.cc
+++ b/libstdc++-v3/src/c++11/locale-inst.cc
@@ -95,7 +95,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
   template class numpunct_byname<C>;
 _GLIBCXX_END_NAMESPACE_CXX11
 _GLIBCXX_BEGIN_NAMESPACE_LDBL
-#if ! _GLIBCXX_USE_CXX11_ABI
+#if GLIBCXX_USE_DUAL_ABI && ! _GLIBCXX_USE_CXX11_ABI
+  template istreambuf_iterator<C>
+    num_get<C, istreambuf_iterator<C>>::
+    _M_extract_float(istreambuf_iterator<C>, istreambuf_iterator<C>,
+		     ios_base&, ios_base::iostate&, string&);
+#else
   template class num_get<C, istreambuf_iterator<C> >;
 #endif
 


More information about the Gcc-patches mailing list