From f3eae68bd1d17df708f2b59a43ad7e837a616e6a Mon Sep 17 00:00:00 2001 From: Derek Mauro Date: Mon, 11 Sep 2023 11:20:53 -0700 Subject: Fixes StrCat() performance regression when not using libc++ 65d7b6d 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 --- absl/strings/str_cat.h | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'absl/strings/str_cat.h') diff --git a/absl/strings/str_cat.h b/absl/strings/str_cat.h index 57a5823f..554c89de 100644 --- a/absl/strings/str_cat.h +++ b/absl/strings/str_cat.h @@ -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 {} && - !std::is_same{}>> +// 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 {} && !std::is_same{}>> using EnableIfFastCase = T; +#undef ABSL_INTERNAL_STRCAT_ENABLE_FAST_CASE + } // namespace strings_internal ABSL_MUST_USE_RESULT inline std::string StrCat() { return std::string(); } -- cgit v1.2.3