[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