[libcxx-commits] [libcxx] 7f65377 - [libc++][format][2/3] Optimizes c-string arguments. (#101805)
via libcxx-commits
libcxx-commits at lists.llvm.org
Sun Oct 6 12:20:26 PDT 2024
Author: Mark de Wever
Date: 2024-10-06T21:20:22+02:00
New Revision: 7f65377880ce6a0e5eaa4cb2591b86b8c8a24ee6
URL: https://github.com/llvm/llvm-project/commit/7f65377880ce6a0e5eaa4cb2591b86b8c8a24ee6
DIFF: https://github.com/llvm/llvm-project/commit/7f65377880ce6a0e5eaa4cb2591b86b8c8a24ee6.diff
LOG: [libc++][format][2/3] Optimizes c-string arguments. (#101805)
The formatter specializations for _CharT* and const _CharT* typically
write all elements in a loop. This format's internal functions are
optimized for larger writes.
Instead of writing one element at a time, convert the range to a
basic_string_view and write that instead.
For C string of 6 characters this is a bit slower, but for 60 characters
it's faster. The improvements for back_inserter<std::list<_CharT>> are
not as great as the others; it just gets as slow as
basic_string_view<_CharT>.
omparing libcxx/test/benchmarks/write_string_comparison.bench.out-before to libcxx/test/benchmarks/write_string_comparison.bench.out-after
Benchmark Time CPU Time Old Time New CPU Old CPU New
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
BM_sprintf/C_string_len_6 -0.0015 +0.0013 5 5 5 5
BM_format/C_string_len_6 +0.0390 +0.0416 53 55 53 55
BM_format_to_back_inserter<std::string>/C_string_len_6 +0.0381 +0.0408 53 55 53 55
BM_format_to_back_inserter<std::vector<char>>/C_string_len_6 +0.0287 +0.0315 69 71 69 71
BM_format_to_back_inserter<std::deque<char>>/C_string_len_6 +0.0503 +0.0530 123 129 123 129
BM_format_to_back_inserter<std::list<char>>/C_string_len_6 -0.0241 -0.0213 133 130 133 130
BM_format_to_iterator/<std::array> C_string_len_6 -0.0075 -0.0049 45 45 45 45
BM_format_to_iterator/<std::string> C_string_len_6 +0.0311 +0.0340 44 46 44 46
BM_format_to_iterator/<std::vector> C_string_len_6 +0.0380 +0.0409 43 45 43 45
BM_format_to_iterator/<std::deque> C_string_len_6 +0.0366 +0.0392 48 50 48 50
BM_format/string_len_6 -0.0010 -0.0007 56 55 55 55
BM_format_to_back_inserter<std::string>/string_len_6 +0.0044 +0.0041 55 56 55 55
BM_format_to_back_inserter<std::vector<char>>/string_len_6 +0.0128 +0.0128 70 71 70 71
BM_format_to_back_inserter<std::deque<char>>/string_len_6 +0.0151 +0.0151 126 128 126 128
BM_format_to_back_inserter<std::list<char>>/string_len_6 -0.0719 -0.0718 140 130 139 129
BM_format_to_iterator/<std::array> string_len_6 -0.0323 -0.0324 47 46 47 46
BM_format_to_iterator/<std::string> string_len_6 -0.0011 -0.0010 45 44 44 44
BM_format_to_iterator/<std::vector> string_len_6 -0.0002 -0.0001 45 45 44 44
BM_format_to_iterator/<std::deque> string_len_6 +0.0046 +0.0047 51 51 51 51
BM_format/string_view_len_6 +0.0031 +0.0031 54 54 54 54
BM_format_to_back_inserter<std::string>/string_view_len_6 +0.0041 +0.0040 54 54 54 54
BM_format_to_back_inserter<std::vector<char>>/string_view_len_6 +0.0022 +0.0022 70 70 70 70
BM_format_to_back_inserter<std::deque<char>>/string_view_len_6 +0.0392 +0.0391 124 129 124 129
BM_format_to_back_inserter<std::list<char>>/string_view_len_6 -0.0680 -0.0680 139 129 138 129
BM_format_to_iterator/<std::array> string_view_len_6 -0.0321 -0.0320 47 46 47 46
BM_format_to_iterator/<std::string> string_view_len_6 -0.0013 -0.0011 45 44 44 44
BM_format_to_iterator/<std::vector> string_view_len_6 -0.0024 -0.0023 45 44 44 44
BM_format_to_iterator/<std::deque> string_view_len_6 +0.0057 +0.0057 51 51 51 51
BM_sprintf/C_string_len_60 -0.0035 -0.0035 4 4 4 4
BM_format/C_string_len_60 -0.5627 -0.5627 169 74 169 74
BM_format_to_back_inserter<std::string>/C_string_len_60 -0.5642 -0.5641 170 74 169 74
BM_format_to_back_inserter<std::vector<char>>/C_string_len_60 -0.5300 -0.5299 178 84 178 84
BM_format_to_back_inserter<std::deque<char>>/C_string_len_60 -0.2548 -0.2548 356 265 355 264
BM_format_to_back_inserter<std::list<char>>/C_string_len_60 -0.1013 -0.1013 1325 1191 1322 1188
BM_format_to_iterator/<std::array> C_string_len_60 -0.6790 -0.6791 141 45 141 45
BM_format_to_iterator/<std::string> C_string_len_60 -0.6738 -0.6740 143 47 142 46
BM_format_to_iterator/<std::vector> C_string_len_60 -0.6807 -0.6808 142 45 142 45
BM_format_to_iterator/<std::deque> C_string_len_60 -0.6488 -0.6486 144 51 144 51
BM_format/string_len_60 +0.0118 +0.0117 73 74 73 73
BM_format_to_back_inserter<std::string>/string_len_60 +0.0089 +0.0088 73 73 73 73
BM_format_to_back_inserter<std::vector<char>>/string_len_60 +0.0080 +0.0081 83 84 83 83
BM_format_to_back_inserter<std::deque<char>>/string_len_60 +0.0005 +0.0002 262 263 262 262
BM_format_to_back_inserter<std::list<char>>/string_len_60 -0.0384 -0.0380 1236 1188 1232 1186
BM_format_to_iterator/<std::array> string_len_60 -0.0288 -0.0288 47 46 47 46
BM_format_to_iterator/<std::string> string_len_60 +0.0213 +0.0210 44 45 44 45
BM_format_to_iterator/<std::vector> string_len_60 +0.0202 +0.0205 45 45 44 45
BM_format_to_iterator/<std::deque> string_len_60 +0.0124 +0.0124 50 51 50 51
BM_format/string_view_len_60 +0.0093 +0.0093 73 73 73 73
BM_format_to_back_inserter<std::string>/string_view_len_60 +0.0055 +0.0055 73 73 73 73
BM_format_to_back_inserter<std::vector<char>>/string_view_len_60 +0.0165 +0.0166 81 83 81 83
BM_format_to_back_inserter<std::deque<char>>/string_view_len_60 +0.0138 +0.0140 260 263 259 263
BM_format_to_back_inserter<std::list<char>>/string_view_len_60 -0.0334 -0.0335 1228 1187 1225 1184
BM_format_to_iterator/<std::array> string_view_len_60 -0.0257 -0.0259 48 46 47 46
BM_format_to_iterator/<std::string> string_view_len_60 +0.0324 +0.0323 45 46 44 46
BM_format_to_iterator/<std::vector> string_view_len_60 +0.0174 +0.0177 45 45 44 45
BM_format_to_iterator/<std::deque> string_view_len_60 +0.0076 +0.0076 50 51 50 51
BM_sprintf/C_string_len_6000 +0.4922 +0.4921 77 115 77 114
BM_format/C_string_len_6000 -0.9239 -0.9239 11780 897 11750 894
BM_format_to_back_inserter<std::string>/C_string_len_6000 -0.9239 -0.9239 11792 898 11763 895
BM_format_to_back_inserter<std::vector<char>>/C_string_len_6000 -0.9257 -0.9257 11709 870 11679 868
BM_format_to_back_inserter<std::deque<char>>/C_string_len_6000 -0.4057 -0.4057 25616 15225 25553 15187
BM_format_to_back_inserter<std::list<char>>/C_string_len_6000 -0.0832 -0.0833 127144 116569 126823 116265
BM_format_to_iterator/<std::array> C_string_len_6000 -0.9853 -0.9853 10869 160 10843 160
BM_format_to_iterator/<std::string> C_string_len_6000 -0.9864 -0.9864 10870 148 10841 148
BM_format_to_iterator/<std::vector> C_string_len_6000 -0.9863 -0.9863 10874 149 10846 148
BM_format_to_iterator/<std::deque> C_string_len_6000 -0.9629 -0.9629 11239 417 11212 416
BM_format/string_len_6000 -0.0012 -0.0013 846 845 844 842
BM_format_to_back_inserter<std::string>/string_len_6000 -0.0029 -0.0034 845 843 843 840
BM_format_to_back_inserter<std::vector<char>>/string_len_6000 -0.0129 -0.0125 832 821 830 819
BM_format_to_back_inserter<std::deque<char>>/string_len_6000 +0.0048 +0.0048 15042 15114 15004 15076
BM_format_to_back_inserter<std::list<char>>/string_len_6000 -0.0017 -0.0017 116266 116072 115967 115768
BM_format_to_iterator/<std::array> string_len_6000 -0.0257 -0.0256 120 117 120 117
BM_format_to_iterator/<std::string> string_len_6000 -0.0025 -0.0029 117 117 117 117
BM_format_to_iterator/<std::vector> string_len_6000 -0.0089 -0.0087 118 116 117 116
BM_format_to_iterator/<std::deque> string_len_6000 -0.0478 -0.0477 379 361 378 360
BM_format/string_view_len_6000 -0.0092 -0.0091 842 835 840 833
BM_format_to_back_inserter<std::string>/string_view_len_6000 -0.0081 -0.0083 841 835 839 832
BM_format_to_back_inserter<std::vector<char>>/string_view_len_6000 +0.0089 +0.0088 808 815 806 813
BM_format_to_back_inserter<std::deque<char>>/string_view_len_6000 +0.0068 +0.0068 15030 15131 14992 15093
BM_format_to_back_inserter<std::list<char>>/string_view_len_6000 +0.0012 +0.0010 116099 116243 115813 115934
BM_format_to_iterator/<std::array> string_view_len_6000 -0.0122 -0.0121 118 117 118 116
BM_format_to_iterator/<std::string> string_view_len_6000 +0.0010 +0.0010 106 107 106 106
BM_format_to_iterator/<std::vector> string_view_len_6000 -0.0008 -0.0006 106 106 106 106
BM_format_to_iterator/<std::deque> string_view_len_6000 -0.0549 -0.0548 370 349 369 349
OVERALL_GEOMEAN
Added:
Modified:
libcxx/include/__format/formatter_string.h
Removed:
################################################################################
diff --git a/libcxx/include/__format/formatter_string.h b/libcxx/include/__format/formatter_string.h
index b29e97847f0ba1..23c880d7c6e844 100644
--- a/libcxx/include/__format/formatter_string.h
+++ b/libcxx/include/__format/formatter_string.h
@@ -64,32 +64,14 @@ struct _LIBCPP_TEMPLATE_VIS formatter<const _CharT*, _CharT> : public __formatte
template <class _FormatContext>
_LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(const _CharT* __str, _FormatContext& __ctx) const {
_LIBCPP_ASSERT_INTERNAL(__str, "The basic_format_arg constructor should have prevented an invalid pointer.");
-
- __format_spec::__parsed_specifications<_CharT> __specs = _Base::__parser_.__get_parsed_std_specifications(__ctx);
-# if _LIBCPP_STD_VER >= 23
- if (_Base::__parser_.__type_ == __format_spec::__type::__debug)
- return __formatter::__format_escaped_string(basic_string_view<_CharT>{__str}, __ctx.out(), __specs);
-# endif
-
- // When using a center or right alignment and the width option the length
- // of __str must be known to add the padding upfront. This case is handled
- // by the base class by converting the argument to a basic_string_view.
+ // Converting the input to a basic_string_view means the data is looped over twice;
+ // - once to determine the length, and
+ // - once to process the data.
//
- // When using left alignment and the width option the padding is added
- // after outputting __str so the length can be determined while outputting
- // __str. The same holds true for the precision, during outputting __str it
- // can be validated whether the precision threshold has been reached. For
- // now these optimizations aren't implemented. Instead the base class
- // handles these options.
- // TODO FMT Implement these improvements.
- if (__specs.__has_width() || __specs.__has_precision())
- return __formatter::__write_string(basic_string_view<_CharT>{__str}, __ctx.out(), __specs);
-
- // No formatting required, copy the string to the output.
- auto __out_it = __ctx.out();
- while (*__str)
- *__out_it++ = *__str++;
- return __out_it;
+ // This sounds slower than writing the output directly. However internally
+ // the output algorithms have optimizations for "bulk" operations, which
+ // makes this faster than a single-pass character-by-character output.
+ return _Base::format(basic_string_view<_CharT>(__str), __ctx);
}
};
More information about the libcxx-commits
mailing list