[libcxx-commits] [libcxx] Optimize __insert_with_sentinel Function in std::vector (PR #113768)

Peng Liu via libcxx-commits libcxx-commits at lists.llvm.org
Thu Nov 7 14:26:06 PST 2024


================
@@ -1360,27 +1360,27 @@ vector<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __position, _Inpu
   for (; this->__end_ != this->__end_cap() && __first != __last; ++__first) {
     __construct_one_at_end(*__first);
   }
-  __split_buffer<value_type, allocator_type&> __v(__a);
-  if (__first != __last) {
-#if _LIBCPP_HAS_EXCEPTIONS
-    try {
-#endif // _LIBCPP_HAS_EXCEPTIONS
-      __v.__construct_at_end_with_sentinel(std::move(__first), std::move(__last));
-      difference_type __old_size = __old_last - this->__begin_;
-      difference_type __old_p    = __p - this->__begin_;
-      reserve(__recommend(size() + __v.size()));
-      __p        = this->__begin_ + __old_p;
-      __old_last = this->__begin_ + __old_size;
-#if _LIBCPP_HAS_EXCEPTIONS
-    } catch (...) {
-      erase(__make_iter(__old_last), end());
-      throw;
-    }
-#endif // _LIBCPP_HAS_EXCEPTIONS
+
+  if (__first == __last)
+    (void)std::rotate(__p, __old_last, this->__end_);
+  else {
+    __split_buffer<value_type, allocator_type&> __v(__a);
+    auto __guard =
+        std::__make_exception_guard(_AllocatorDestroyRangeReverse<allocator_type, pointer>(__a, __old_last, __end_));
----------------
winner245 wrote:

I've added new benchmark tests for `vector::insert(const_iterator, _InputIterator, _InputIterator)` and performed local testing for `std::vector<int>` and `std::vector<std::string>`. The results show significant performance improvements in various scenarios.

For `std::vector<int>`, I tested inserting an input iterator range into an empty, half-full, and nearly-full vector. My local testing demonstrated performance improvements of 1.3x, 1.2x, and 5.8x respectively after applying this patch. Similarly, for std::vector<std::string>, my local testing demonstrated performance improvements of 1.3x, 1.5x, and 3.2x for an empty, half-full, and nearly full vector, respectively. 

- Before:
![before1](https://github.com/user-attachments/assets/c5cd9504-1848-4e7c-9cac-7ff9552a23eb)


- After:
![after1](https://github.com/user-attachments/assets/ecbbbdcc-f2b0-4da6-81a4-cf94b77fde40)



https://github.com/llvm/llvm-project/pull/113768


More information about the libcxx-commits mailing list