public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
* [committed] libstdc++: Optimize std::ostream inserters for single characters
@ 2022-01-11 13:28 Jonathan Wakely
  0 siblings, 0 replies; only message in thread
From: Jonathan Wakely @ 2022-01-11 13:28 UTC (permalink / raw)
  To: libstdc++, gcc-patches; +Cc: Lewis Hyatt

Tested x86_64-linux. Pushed to trunk.


On the libsdc++ mailing list Lewis Hyatt pointed out the performance
overhead of using sputn in stream inserters, rather than writing
directly to the streambuf's put area:
https://gcc.gnu.org/pipermail/libstdc++/2021-July/052877.html

As Lewis noted, the standard explicitly requires a call to sputn for
inserting a std::basic_string_view or std::basic_string.  But for
inserting single characters or null-terminated strings it is more vague,
and so we can improve performance by not using the __ostream_insert
function.

This is a minimal change that avoids __ostream_insert for single
characters. We can use the unformatted basic_ostream::put(charT)
function when we don't need the additional effects of a formatted output
function (i.e. padding and resetting the width). The put function will
insert into the buffer if possible, and only make a virtual call (to
overflow) if the buffer is full.

We could also avoid sputn when inserting null-terminated character
strings, but that would require using a new function for inserting
null-terminated strings, so the existing code using sputn is still used
for basic_string and basic_string_view. My preference is to leave that
for now, and try to improve the standard. We could either remove the
requirement to call sputn, or allow sputn to write directly to the
buffer instead of calling xsputn.

libstdc++-v3/ChangeLog:

	* include/std/ostream (operator<<(basic_ostream&, charT)):
	Use unformatted input if no padding is needed.
	(operator<<(basic_ostream<char>&, char)): Likewise.
---
 libstdc++-v3/include/std/ostream | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream
index f8073f2a9b7..291ea40b355 100644
--- a/libstdc++-v3/include/std/ostream
+++ b/libstdc++-v3/include/std/ostream
@@ -505,7 +505,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _CharT, typename _Traits>
     inline basic_ostream<_CharT, _Traits>&
     operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)
-    { return __ostream_insert(__out, &__c, 1); }
+    {
+      if (__out.width() != 0)
+	return __ostream_insert(__out, &__c, 1);
+      __out.put(__c);
+      return __out;
+    }
 
   template<typename _CharT, typename _Traits>
     inline basic_ostream<_CharT, _Traits>&
@@ -516,7 +521,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Traits>
     inline basic_ostream<char, _Traits>&
     operator<<(basic_ostream<char, _Traits>& __out, char __c)
-    { return __ostream_insert(__out, &__c, 1); }
+    {
+      if (__out.width() != 0)
+	return __ostream_insert(__out, &__c, 1);
+      __out.put(__c);
+      return __out;
+    }
 
   // Signed and unsigned
   template<typename _Traits>
-- 
2.31.1


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

only message in thread, other threads:[~2022-01-11 13:28 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-11 13:28 [committed] libstdc++: Optimize std::ostream inserters for single characters 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).