public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-9377] libstdc++: Use std::from_chars to speed up parsing subsecond durations
@ 2024-03-08  0:10 Jonathan Wakely
  0 siblings, 0 replies; only message in thread
From: Jonathan Wakely @ 2024-03-08  0:10 UTC (permalink / raw)
  To: gcc-cvs, libstdc++-cvs

https://gcc.gnu.org/g:715127b63d19ed3b9a92d3e5f5007b36cc9834dd

commit r14-9377-g715127b63d19ed3b9a92d3e5f5007b36cc9834dd
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu Mar 7 13:47:46 2024 +0000

    libstdc++: Use std::from_chars to speed up parsing subsecond durations
    
    With std::from_chars we can parse subsecond durations much faster than
    with std::num_get, as shown in the microbenchmarks below. We were using
    std::num_get and std::numpunct in order to parse a number with the
    locale's decimal point character. But we copy the chars from the input
    stream into a new buffer anyway, so we can replace the locale's decimal
    point with '.' in that buffer, and then we can use std::from_chars on
    it.
    
    Benchmark                Time             CPU   Iterations
    ----------------------------------------------------------
    from_chars_millisec    158 ns          158 ns      4524046
    num_get_millisec       192 ns          192 ns      3644626
    from_chars_microsec    164 ns          163 ns      4330627
    num_get_microsec       205 ns          205 ns      3413452
    from_chars_nanosec     173 ns          173 ns      4072653
    num_get_nanosec        227 ns          227 ns      3105161
    
    libstdc++-v3/ChangeLog:
    
            * include/bits/chrono_io.h (_Parser::operator()): Use
            std::from_chars to parse fractional seconds.

Diff:
---
 libstdc++-v3/include/bits/chrono_io.h | 28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/libstdc++-v3/include/bits/chrono_io.h b/libstdc++-v3/include/bits/chrono_io.h
index b8f0657bee9..412e8b83fb7 100644
--- a/libstdc++-v3/include/bits/chrono_io.h
+++ b/libstdc++-v3/include/bits/chrono_io.h
@@ -37,6 +37,7 @@
 #include <sstream> // ostringstream
 #include <iomanip> // setw, setfill
 #include <format>
+#include <charconv> // from_chars
 
 #include <bits/streambuf_iterator.h>
 
@@ -3597,13 +3598,17 @@ namespace __detail
 			__err |= ios_base::eofbit;
 		      else
 			{
-			  auto& __np = use_facet<numpunct<_CharT>>(__loc);
-			  auto __dp = __np.decimal_point();
+			  _CharT __dp = '.';
+			  if (__loc != locale::classic())
+			    {
+			      auto& __np = use_facet<numpunct<_CharT>>(__loc);
+			      __dp = __np.decimal_point();
+			    }
 			  _CharT __c = _Traits::to_char_type(__i);
 			  if (__c == __dp)
 			    {
 			      (void) __is.get();
-			      __buf.put(__c);
+			      __buf.put('.');
 			      int __prec
 				= hh_mm_ss<_Duration>::fractional_width;
 			      do
@@ -3618,14 +3623,17 @@ namespace __detail
 			    }
 			}
 
-		      if (!__is_failed(__err))
+		      if (!__is_failed(__err)) [[likely]]
 			{
-			  auto& __ng = use_facet<num_get<_CharT>>(__loc);
-			  long double __val;
-			  ios_base::iostate __err2{};
-			  __ng.get(__buf, {}, __buf, __err2, __val);
-			  if (__is_failed(__err2)) [[unlikely]]
-			    __err |= __err2;
+			  long double __val{};
+			  string __str = std::move(__buf).str();
+			  auto __first = __str.data();
+			  auto __last = __first + __str.size();
+			  using enum chars_format;
+			  auto [ptr, ec] = std::from_chars(__first, __last,
+							   __val, fixed);
+			  if ((bool)ec || ptr != __last) [[unlikely]]
+			    __err |= ios_base::failbit;
 			  else
 			    {
 			      duration<long double> __fs(__val);

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-03-08  0:10 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-08  0:10 [gcc r14-9377] libstdc++: Use std::from_chars to speed up parsing subsecond durations Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).