Commit f3eae68b by Derek Mauro Committed by Copybara-Service

Fixes StrCat() performance regression when not using libc++

65d7b6d4 changed StrCat() to not use an intermediate buffer when the
result fits in the SSO buffer, but only libc++ has an SSO buffer large
enough for this optimization to work.

PiperOrigin-RevId: 564447163
Change-Id: I0c7fa4afed3369b36e13e7d1691eb7f933ea0091
parent 317085ad
......@@ -498,11 +498,28 @@ inline std::string SingleArgStrCat(unsigned long long x) {
inline std::string SingleArgStrCat(float x) { return FloatToString(x); }
inline std::string SingleArgStrCat(double x) { return FloatToString(x); }
template <typename T, typename = std::enable_if_t<std::is_arithmetic<T>{} &&
!std::is_same<T, char>{}>>
// As of September 2023, the SingleArgStrCat() optimization is only enabled for
// libc++. The reasons for this are:
// 1) The SSO size for libc++ is 23, while libstdc++ and MSSTL have an SSO size
// of 15. Since IntegerToString unconditionally resizes the string to 22 bytes,
// this causes both libstdc++ and MSSTL to allocate.
// 2) strings_internal::STLStringResizeUninitialized() only has an
// implementation that avoids initialization when using libc++. This isn't as
// relevant as (1), and the cost should be benchmarked if (1) ever changes on
// libstc++ or MSSTL.
#ifdef _LIBCPP_VERSION
#define ABSL_INTERNAL_STRCAT_ENABLE_FAST_CASE true
#else
#define ABSL_INTERNAL_STRCAT_ENABLE_FAST_CASE false
#endif
template <typename T, typename = std::enable_if_t<
ABSL_INTERNAL_STRCAT_ENABLE_FAST_CASE &&
std::is_arithmetic<T>{} && !std::is_same<T, char>{}>>
using EnableIfFastCase = T;
#undef ABSL_INTERNAL_STRCAT_ENABLE_FAST_CASE
} // namespace strings_internal
ABSL_MUST_USE_RESULT inline std::string StrCat() { return std::string(); }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment