[libcxx-commits] [libcxx] [libcxx] Speed up xsgetn for always_noconv (PR #212010)
via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Jul 25 03:48:37 PDT 2026
https://github.com/aokblast created https://github.com/llvm/llvm-project/pull/212010
In the always_noconv path, optimize character reads in the same way as xsgetn.
Unlike fread, getwc has different semantics, so the same optimization cannot be applied to wide characters. Therefore, only optimize the char path.
>From 3fe8ab44b769ed1a0c79f21a2643485ada4780dd Mon Sep 17 00:00:00 2001
From: ShengYi Hung <aokblast at FreeBSD.org>
Date: Sat, 25 Jul 2026 18:42:41 +0800
Subject: [PATCH] [libcxx] Speed up xsgetn for always_noconv
In the always_noconv path, optimize character reads in the same way as
xsgetn.
Unlike fread, getwc has different semantics, so the same optimization
cannot be applied to wide characters. Therefore, only optimize the char
path.
---
libcxx/src/std_stream.h | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/libcxx/src/std_stream.h b/libcxx/src/std_stream.h
index 4b9d3a34b2441..214acc9e88b70 100644
--- a/libcxx/src/std_stream.h
+++ b/libcxx/src/std_stream.h
@@ -45,6 +45,7 @@ class _LIBCPP_HIDDEN __stdinbuf : public basic_streambuf<_CharT, char_traits<_Ch
protected:
virtual int_type underflow();
virtual int_type uflow();
+ virtual streamsize xsgetn(char_type* __s, streamsize __n);
virtual int_type pbackfail(int_type __c = traits_type::eof());
virtual void imbue(const locale& __loc);
@@ -199,6 +200,28 @@ typename __stdinbuf<_CharT>::int_type __stdinbuf<_CharT>::__getchar(bool __consu
return traits_type::to_int_type(__1buf);
}
+template <class _CharT>
+streamsize __stdinbuf<_CharT>::xsgetn(char_type* __s, streamsize __n) {
+ if constexpr (is_same<_CharT, char>::value) {
+ if (__always_noconv_) {
+ streamsize __i = 0;
+ if (__i < __n && __last_consumed_is_next_) {
+ __s[__i++] = traits_type::to_char_type(__last_consumed_);
+ __last_consumed_ = traits_type::eof();
+ __last_consumed_is_next_ = false;
+ }
+ if (__i < __n) {
+ size_t __nread = fread(__s + __i, 1, static_cast<size_t>(__n - __i), __file_);
+ if (__nread > 0)
+ __last_consumed_ = traits_type::to_int_type(__s[__i + __nread - 1]);
+ __i += static_cast<streamsize>(__nread);
+ }
+ return __i;
+ }
+ }
+ return basic_streambuf<char_type, traits_type>::xsgetn(__s, __n);
+}
+
template <class _CharT>
typename __stdinbuf<_CharT>::int_type __stdinbuf<_CharT>::pbackfail(int_type __c) {
if (traits_type::eq_int_type(__c, traits_type::eof())) {
More information about the libcxx-commits
mailing list