summaryrefslogtreecommitdiff
path: root/absl/strings/str_cat.h
diff options
context:
space:
mode:
authorGravatar Derek Mauro <dmauro@google.com>2023-09-11 11:20:53 -0700
committerGravatar Copybara-Service <copybara-worker@google.com>2023-09-11 11:22:15 -0700
commitf3eae68bd1d17df708f2b59a43ad7e837a616e6a (patch)
treed292bc842785f0d734d10cbc0e35431547924543 /absl/strings/str_cat.h
parent317085adc4e4e474eb4546fa9d37f74c61d95f7f (diff)
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
Diffstat (limited to 'absl/strings/str_cat.h')
-rw-r--r--absl/strings/str_cat.h23
1 files changed, 20 insertions, 3 deletions
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 <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(); }