]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/move/test/bench_sort.cpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / libs / move / test / bench_sort.cpp
CommitLineData
7c673cae
FG
1//////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Ion Gaztanaga 2015-2016.
4// Distributed under the Boost Software License, Version 1.0.
5// (See accompanying file LICENSE_1_0.txt or copy at
6// http://www.boost.org/LICENSE_1_0.txt)
7//
8// See http://www.boost.org/libs/move for documentation.
9//
10//////////////////////////////////////////////////////////////////////////////
11
12#include <cstdlib> //std::srand
13#include <algorithm> //std::stable_sort, std::make|sort_heap, std::random_shuffle
14#include <cstdio> //std::printf
15#include <iostream> //std::cout
92f5a8d4 16#include <boost/container/vector.hpp> //boost::container::vector
7c673cae
FG
17
18#include <boost/config.hpp>
7c673cae 19#include <boost/move/unique_ptr.hpp>
20effc67
TL
20#include <boost/move/detail/nsec_clock.hpp>
21#include <cstdlib>
7c673cae 22
20effc67
TL
23using boost::move_detail::cpu_timer;
24using boost::move_detail::nanosecond_type;
7c673cae
FG
25
26#include "order_type.hpp"
b32b8144 27#include "random_shuffle.hpp"
7c673cae
FG
28
29//#define BOOST_MOVE_ADAPTIVE_SORT_STATS
b32b8144 30//#define BOOST_MOVE_ADAPTIVE_SORT_INVARIANTS
7c673cae
FG
31void print_stats(const char *str, boost::ulong_long_type element_count)
32{
b32b8144 33 std::printf("%sCmp:%7.03f Cpy:%8.03f\n", str, double(order_perf_type::num_compare)/element_count, double(order_perf_type::num_copy)/element_count );
7c673cae
FG
34}
35
36
37#include <boost/move/algo/adaptive_sort.hpp>
38#include <boost/move/algo/detail/merge_sort.hpp>
11fdf7f2
TL
39#include <boost/move/algo/detail/pdqsort.hpp>
40#include <boost/move/algo/detail/heap_sort.hpp>
7c673cae
FG
41#include <boost/move/core.hpp>
42
43template<class T>
92f5a8d4 44void generate_elements(boost::container::vector<T> &elements, std::size_t L, std::size_t NK)
7c673cae 45{
92f5a8d4
TL
46 elements.resize(L);
47 boost::movelib::unique_ptr<std::size_t[]> key_reps(new std::size_t[NK ? NK : L]);
48
7c673cae 49 std::srand(0);
92f5a8d4
TL
50 for (std::size_t i = 0; i < (NK ? NK : L); ++i) {
51 key_reps[i] = 0;
7c673cae 52 }
92f5a8d4
TL
53 for (std::size_t i = 0; i < L; ++i) {
54 std::size_t key = NK ? (i % NK) : i;
55 elements[i].key = key;
7c673cae 56 }
92f5a8d4
TL
57 ::random_shuffle(elements.data(), elements.data() + L);
58 ::random_shuffle(elements.data(), elements.data() + L);
59
60 for (std::size_t i = 0; i < L; ++i) {
7c673cae
FG
61 elements[i].val = key_reps[elements[i].key]++;
62 }
63}
64
65template<class T, class Compare>
66void adaptive_sort_buffered(T *elements, std::size_t element_count, Compare comp, std::size_t BufLen)
67{
68 boost::movelib::unique_ptr<char[]> mem(new char[sizeof(T)*BufLen]);
69 boost::movelib::adaptive_sort(elements, elements + element_count, comp, reinterpret_cast<T*>(mem.get()), BufLen);
70}
71
92f5a8d4
TL
72template<class T, class Compare>
73void std_like_adaptive_stable_sort_buffered(T *elements, std::size_t element_count, Compare comp, std::size_t BufLen)
74{
75 boost::movelib::unique_ptr<char[]> mem(new char[sizeof(T)*BufLen]);
76 boost::movelib::stable_sort_adaptive_ONlogN2(elements, elements + element_count, comp, reinterpret_cast<T*>(mem.get()), BufLen);
77}
78
7c673cae
FG
79template<class T, class Compare>
80void merge_sort_buffered(T *elements, std::size_t element_count, Compare comp)
81{
82 boost::movelib::unique_ptr<char[]> mem(new char[sizeof(T)*((element_count+1)/2)]);
83 boost::movelib::merge_sort(elements, elements + element_count, comp, reinterpret_cast<T*>(mem.get()));
84}
85
86enum AlgoType
87{
88 MergeSort,
89 StableSort,
11fdf7f2
TL
90 PdQsort,
91 StdSort,
7c673cae
FG
92 AdaptiveSort,
93 SqrtHAdaptiveSort,
94 SqrtAdaptiveSort,
95 Sqrt2AdaptiveSort,
96 QuartAdaptiveSort,
7c673cae 97 InplaceStableSort,
92f5a8d4
TL
98 StdSqrtHAdpSort,
99 StdSqrtAdpSort,
100 StdSqrt2AdpSort,
101 StdQuartAdpSort,
7c673cae
FG
102 SlowStableSort,
103 HeapSort,
104 MaxSort
105};
106
107const char *AlgoNames [] = { "MergeSort "
108 , "StableSort "
11fdf7f2
TL
109 , "PdQsort "
110 , "StdSort "
7c673cae
FG
111 , "AdaptSort "
112 , "SqrtHAdaptSort "
113 , "SqrtAdaptSort "
114 , "Sqrt2AdaptSort "
115 , "QuartAdaptSort "
7c673cae 116 , "InplStableSort "
92f5a8d4
TL
117 , "StdSqrtHAdpSort"
118 , "StdSqrtAdpSort "
119 , "StdSqrt2AdpSort"
120 , "StdQuartAdpSort"
7c673cae
FG
121 , "SlowSort "
122 , "HeapSort "
123 };
124
125BOOST_STATIC_ASSERT((sizeof(AlgoNames)/sizeof(*AlgoNames)) == MaxSort);
126
127template<class T>
92f5a8d4 128bool measure_algo(T *elements, std::size_t element_count, std::size_t alg, nanosecond_type &prev_clock)
7c673cae 129{
7c673cae 130 std::printf("%s ", AlgoNames[alg]);
b32b8144
FG
131 order_perf_type::num_compare=0;
132 order_perf_type::num_copy=0;
133 order_perf_type::num_elements = element_count;
7c673cae
FG
134 cpu_timer timer;
135 timer.resume();
136 switch(alg)
137 {
138 case MergeSort:
b32b8144 139 merge_sort_buffered(elements, element_count, order_type_less());
7c673cae
FG
140 break;
141 case StableSort:
b32b8144 142 std::stable_sort(elements,elements+element_count,order_type_less());
7c673cae 143 break;
11fdf7f2
TL
144 case PdQsort:
145 boost::movelib::pdqsort(elements,elements+element_count,order_type_less());
146 break;
147 case StdSort:
148 std::sort(elements,elements+element_count,order_type_less());
149 break;
7c673cae 150 case AdaptiveSort:
b32b8144 151 boost::movelib::adaptive_sort(elements, elements+element_count, order_type_less());
7c673cae
FG
152 break;
153 case SqrtHAdaptiveSort:
b32b8144 154 adaptive_sort_buffered( elements, element_count, order_type_less()
7c673cae
FG
155 , boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count)/2+1);
156 break;
157 case SqrtAdaptiveSort:
b32b8144 158 adaptive_sort_buffered( elements, element_count, order_type_less()
7c673cae
FG
159 , boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count));
160 break;
161 case Sqrt2AdaptiveSort:
b32b8144 162 adaptive_sort_buffered( elements, element_count, order_type_less()
7c673cae
FG
163 , 2*boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count));
164 break;
165 case QuartAdaptiveSort:
b32b8144 166 adaptive_sort_buffered( elements, element_count, order_type_less()
7c673cae
FG
167 , (element_count-1)/4+1);
168 break;
7c673cae 169 case InplaceStableSort:
b32b8144 170 boost::movelib::inplace_stable_sort(elements, elements+element_count, order_type_less());
7c673cae 171 break;
92f5a8d4
TL
172 case StdSqrtHAdpSort:
173 std_like_adaptive_stable_sort_buffered( elements, element_count, order_type_less()
174 , boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count)/2+1);
175 break;
176 case StdSqrtAdpSort:
177 std_like_adaptive_stable_sort_buffered( elements, element_count, order_type_less()
178 , boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count));
179 break;
180 case StdSqrt2AdpSort:
181 std_like_adaptive_stable_sort_buffered( elements, element_count, order_type_less()
182 , 2*boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count));
183 break;
184 case StdQuartAdpSort:
185 std_like_adaptive_stable_sort_buffered( elements, element_count, order_type_less()
186 , (element_count-1)/4+1);
187 break;
7c673cae 188 case SlowStableSort:
b32b8144 189 boost::movelib::detail_adaptive::slow_stable_sort(elements, elements+element_count, order_type_less());
7c673cae
FG
190 break;
191 case HeapSort:
11fdf7f2
TL
192 boost::movelib::heap_sort(elements, elements+element_count, order_type_less());
193 boost::movelib::heap_sort((order_move_type*)0, (order_move_type*)0, order_type_less());
194
7c673cae
FG
195 break;
196 }
197 timer.stop();
198
b32b8144 199 if(order_perf_type::num_elements == element_count){
7c673cae
FG
200 std::printf(" Tmp Ok ");
201 } else{
202 std::printf(" Tmp KO ");
203 }
204 nanosecond_type new_clock = timer.elapsed().wall;
205
b32b8144
FG
206 //std::cout << "Cmp:" << order_perf_type::num_compare << " Cpy:" << order_perf_type::num_copy; //for old compilers without ll size argument
207 std::printf("Cmp:%7.03f Cpy:%8.03f", double(order_perf_type::num_compare)/element_count, double(order_perf_type::num_copy)/element_count );
7c673cae
FG
208
209 double time = double(new_clock);
210
211 const char *units = "ns";
212 if(time >= 1000000000.0){
213 time /= 1000000000.0;
214 units = " s";
215 }
216 else if(time >= 1000000.0){
217 time /= 1000000.0;
218 units = "ms";
219 }
220 else if(time >= 1000.0){
221 time /= 1000.0;
222 units = "us";
223 }
224
225 std::printf(" %6.02f%s (%6.02f)\n"
226 , time
227 , units
228 , prev_clock ? double(new_clock)/double(prev_clock): 1.0);
229 prev_clock = new_clock;
11fdf7f2 230 bool res = is_order_type_ordered(elements, element_count, alg != HeapSort && alg != PdQsort && alg != StdSort);
7c673cae
FG
231 return res;
232}
233
234template<class T>
235bool measure_all(std::size_t L, std::size_t NK)
236{
92f5a8d4
TL
237 boost::container::vector<T> original_elements, elements;
238 generate_elements(original_elements, L, NK);
7c673cae
FG
239 std::printf("\n - - N: %u, NK: %u - -\n", (unsigned)L, (unsigned)NK);
240
241 nanosecond_type prev_clock = 0;
242 nanosecond_type back_clock;
243 bool res = true;
92f5a8d4
TL
244 elements = original_elements;
245 res = res && measure_algo(elements.data(), L,MergeSort, prev_clock);
7c673cae
FG
246 back_clock = prev_clock;
247 //
248 prev_clock = back_clock;
92f5a8d4
TL
249 elements = original_elements;
250 res = res && measure_algo(elements.data(), L,StableSort, prev_clock);
251 //
252 prev_clock = back_clock;
253 elements = original_elements;
254 res = res && measure_algo(elements.data(), L,PdQsort, prev_clock);
7c673cae
FG
255 //
256 prev_clock = back_clock;
92f5a8d4
TL
257 elements = original_elements;
258 res = res && measure_algo(elements.data(), L,StdSort, prev_clock);
11fdf7f2
TL
259 //
260 prev_clock = back_clock;
92f5a8d4
TL
261 elements = original_elements;
262 res = res && measure_algo(elements.data(), L,HeapSort, prev_clock);
11fdf7f2
TL
263 //
264 prev_clock = back_clock;
92f5a8d4
TL
265 elements = original_elements;
266 res = res && measure_algo(elements.data(), L,QuartAdaptiveSort, prev_clock);
7c673cae
FG
267 //
268 prev_clock = back_clock;
92f5a8d4
TL
269 elements = original_elements;
270 res = res && measure_algo(elements.data(), L, StdQuartAdpSort, prev_clock);
7c673cae
FG
271 //
272 prev_clock = back_clock;
92f5a8d4
TL
273 elements = original_elements;
274 res = res && measure_algo(elements.data(), L,Sqrt2AdaptiveSort, prev_clock);
7c673cae
FG
275 //
276 prev_clock = back_clock;
92f5a8d4
TL
277 elements = original_elements;
278 res = res && measure_algo(elements.data(), L, StdSqrt2AdpSort, prev_clock);
7c673cae
FG
279 //
280 prev_clock = back_clock;
92f5a8d4
TL
281 elements = original_elements;
282 res = res && measure_algo(elements.data(), L,SqrtAdaptiveSort, prev_clock);
7c673cae
FG
283 //
284 prev_clock = back_clock;
92f5a8d4
TL
285 elements = original_elements;
286 res = res && measure_algo(elements.data(), L, StdSqrtAdpSort, prev_clock);
7c673cae
FG
287 //
288 prev_clock = back_clock;
92f5a8d4
TL
289 elements = original_elements;
290 res = res && measure_algo(elements.data(), L,SqrtHAdaptiveSort, prev_clock);
291 //
292 prev_clock = back_clock;
293 elements = original_elements;
294 res = res && measure_algo(elements.data(), L, StdSqrtHAdpSort, prev_clock);
295 //
296 prev_clock = back_clock;
297 elements = original_elements;
298 res = res && measure_algo(elements.data(), L,AdaptiveSort, prev_clock);
299 //
300 prev_clock = back_clock;
301 elements = original_elements;
302 res = res && measure_algo(elements.data(), L,InplaceStableSort, prev_clock);
7c673cae 303 //
7c673cae 304 //prev_clock = back_clock;
92f5a8d4
TL
305 //elements = original_elements;
306 //res = res && measure_algo(elements.data(), L,SlowStableSort, prev_clock);
20effc67 307
7c673cae 308 if(!res)
20effc67 309 std::abort();
7c673cae
FG
310 return res;
311}
312
313//Undef it to run the long test
314#define BENCH_SORT_SHORT
315#define BENCH_SORT_UNIQUE_VALUES
316
317int main()
318{
319 #ifndef BENCH_SORT_UNIQUE_VALUES
b32b8144
FG
320 measure_all<order_perf_type>(101,1);
321 measure_all<order_perf_type>(101,7);
322 measure_all<order_perf_type>(101,31);
7c673cae 323 #endif
b32b8144 324 measure_all<order_perf_type>(101,0);
7c673cae
FG
325
326 //
327 #ifndef BENCH_SORT_UNIQUE_VALUES
b32b8144
FG
328 measure_all<order_perf_type>(1101,1);
329 measure_all<order_perf_type>(1001,7);
330 measure_all<order_perf_type>(1001,31);
331 measure_all<order_perf_type>(1001,127);
332 measure_all<order_perf_type>(1001,511);
7c673cae 333 #endif
b32b8144 334 measure_all<order_perf_type>(1001,0);
7c673cae 335 //
7c673cae 336 #ifndef BENCH_SORT_UNIQUE_VALUES
b32b8144
FG
337 measure_all<order_perf_type>(10001,65);
338 measure_all<order_perf_type>(10001,255);
339 measure_all<order_perf_type>(10001,1023);
340 measure_all<order_perf_type>(10001,4095);
7c673cae 341 #endif
b32b8144 342 measure_all<order_perf_type>(10001,0);
7c673cae
FG
343
344 //
92f5a8d4 345 #ifdef NDEBUG
7c673cae 346 #ifndef BENCH_SORT_UNIQUE_VALUES
b32b8144
FG
347 measure_all<order_perf_type>(100001,511);
348 measure_all<order_perf_type>(100001,2047);
349 measure_all<order_perf_type>(100001,8191);
350 measure_all<order_perf_type>(100001,32767);
7c673cae 351 #endif
b32b8144 352 measure_all<order_perf_type>(100001,0);
7c673cae
FG
353
354 //
92f5a8d4 355 #ifndef BENCH_SORT_SHORT
7c673cae 356 #ifndef BENCH_SORT_UNIQUE_VALUES
92f5a8d4
TL
357 measure_all<order_perf_type>(1000001, 8192);
358 measure_all<order_perf_type>(1000001, 32768);
359 measure_all<order_perf_type>(1000001, 131072);
360 measure_all<order_perf_type>(1000001, 524288);
7c673cae 361 #endif
b32b8144 362 measure_all<order_perf_type>(1000001,0);
7c673cae 363
92f5a8d4
TL
364 #ifndef BENCH_SORT_UNIQUE_VALUES
365 measure_all<order_perf_type>(10000001, 65536);
366 measure_all<order_perf_type>(10000001, 262144);
367 measure_all<order_perf_type>(10000001, 1048576);
368 measure_all<order_perf_type>(10000001, 4194304);
369 #endif
370 measure_all<order_perf_type>(1000001,0);
7c673cae 371 #endif //#ifndef BENCH_SORT_SHORT
92f5a8d4 372 #endif //NDEBUG
7c673cae 373
b32b8144 374 //measure_all<order_perf_type>(100000001,0);
7c673cae
FG
375
376 return 0;
377}