[libcxx-commits] [PATCH] D72165: Optimize / partially inline basic_string assignment operator

Martijn Vels via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Fri Jan 3 09:10:20 PST 2020


mvels created this revision.
Herald added subscribers: libcxx-commits, christof.
Herald added a project: libc++.

This change adds an optimization where assigning a short string value to a short string instance is optimized into a direct memory copy.

'As is', this optimization provides a 2X to 3X+ speed up.

BM_StringAssignStr_Empty_Opaque 5.23ns ± 0% 2.27ns ± 0% -56.62% (p=0.008 n=5+5)
BM_StringAssignStr_Empty_Transparent 5.14ns ± 0% 2.27ns ± 0% -55.89% (p=0.008 n=5+5)
BM_StringAssignStr_Small_Opaque 7.69ns ± 0% 2.27ns ± 0% -70.56% (p=0.008 n=5+5)
BM_StringAssignStr_Small_Transparent 7.65ns ± 0% 2.26ns ± 0% -70.41% (p=0.008 n=5+5)
BM_StringAssignStr_Large_Opaque 24.4ns ± 0% 25.6ns ± 0% +5.11% (p=0.008 n=5+5)
BM_StringAssignStr_Large_Transparent 22.2ns ± 0% 22.9ns ± 0% +3.43% (p=0.008 n=5+5)
BM_StringAssignStr_Huge_Opaque 320ns ± 3% 320ns ± 4% ~ (p=0.841 n=5+5)
BM_StringAssignStr_Huge_Transparent 321ns ± 4% 321ns ± 4% ~ (p=1.000 n=5+5)

Subsequently changing the assignment operator to be inlined (not externally instantiated) provides a speed up of 3X to 5X.

BM_StringAssignStr_Empty_Opaque 5.25ns ± 1% 1.71ns ± 0% -67.33% (p=0.008 n=5+5)
BM_StringAssignStr_Empty_Transparent 5.13ns ± 0% 1.29ns ± 0% -74.89% (p=0.008 n=5+5)
BM_StringAssignStr_Small_Opaque 7.69ns ± 0% 1.71ns ± 0% -77.70% (p=0.008 n=5+5)
BM_StringAssignStr_Small_Transparent 7.64ns ± 0% 1.29ns ± 0% -83.10% (p=0.008 n=5+5)
BM_StringAssignStr_Large_Opaque 24.4ns ± 0% 25.3ns ± 0% +3.97% (p=0.008 n=5+5)
BM_StringAssignStr_Large_Transparent 22.2ns ± 0% 22.6ns ± 0% +2.13% (p=0.008 n=5+5)
BM_StringAssignStr_Huge_Opaque 325ns ± 5% 315ns ± 6% ~ (p=0.222 n=5+5)
BM_StringAssignStr_Huge_Transparent 325ns ± 5% 316ns ± 5% ~ (p=0.310 n=5+5)


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D72165

Files:
  libcxx/include/string


Index: libcxx/include/string
===================================================================
--- libcxx/include/string
+++ libcxx/include/string
@@ -874,6 +874,7 @@
     _LIBCPP_INLINE_VISIBILITY
     operator __self_view() const _NOEXCEPT { return __self_view(data(), size()); }
 
+    // Optimization opportunity: do not externally instantiate
     basic_string& operator=(const basic_string& __str);
 
     template <class _Tp, class = typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type>
@@ -2266,7 +2267,10 @@
     if (this != &__str)
     {
         __copy_assign_alloc(__str);
-        return assign(__str.data(), __str.size());
+        if (__is_long() | __str.__is_long()) {  // LINT: explicit binary or.
+          return assign(__str.data(), __str.size());
+        }
+        __r_.first().__r = __str.__r_.first().__r;
     }
     return *this;
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D72165.236076.patch
Type: text/x-patch
Size: 907 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20200103/c57f8c70/attachment.bin>


More information about the libcxx-commits mailing list