benchmark_numbers.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. //----------------------------------------------------------------------------
  2. /// @file benchmark_numbers.cpp
  3. /// @brief Benchmark of several sort methods with integer objects
  4. ///
  5. /// @author Copyright (c) 2017 Francisco José Tapia (fjtapia@gmail.com )\n
  6. /// Distributed under the Boost Software License, Version 1.0.\n
  7. /// ( See accompanying file LICENSE_1_0.txt or copy at
  8. /// http://www.boost.org/LICENSE_1_0.txt )
  9. ///
  10. /// This program use for comparison purposes, the Threading Building
  11. /// Blocks which license is the GNU General Public License, version 2
  12. /// as published by the Free Software Foundation.
  13. ///
  14. /// @version 0.1
  15. ///
  16. /// @remarks
  17. //-----------------------------------------------------------------------------
  18. #include <algorithm>
  19. #include <iostream>
  20. #include <iomanip>
  21. #include <random>
  22. #include <stdlib.h>
  23. #include <vector>
  24. #include <boost/sort/common/time_measure.hpp>
  25. #include <boost/sort/common/file_vector.hpp>
  26. #include <boost/sort/common/int_array.hpp>
  27. #include <boost/sort/sort.hpp>
  28. #define NELEM 100000000
  29. using namespace std;
  30. namespace bsort = boost::sort;
  31. namespace bsc = boost::sort::common;
  32. using bsc::time_point;
  33. using bsc::now;
  34. using bsc::subtract_time;
  35. using bsc::fill_vector_uint64;
  36. using bsc::write_file_uint64;
  37. using bsort::spinsort;
  38. using bsort::flat_stable_sort;
  39. using bsort::spreadsort::spreadsort;
  40. using bsort::pdqsort;
  41. void Generator_random (void);
  42. void Generator_sorted (void);
  43. void Generator_sorted_end (size_t n_last);
  44. void Generator_sorted_middle (size_t n_last);
  45. void Generator_reverse_sorted (void);
  46. void Generator_reverse_sorted_end (size_t n_last);
  47. void Generator_reverse_sorted_middle (size_t n_last);
  48. template<class IA, class compare>
  49. int Test (std::vector<IA> &B, compare comp = compare ());
  50. int main (int argc, char *argv[])
  51. {
  52. cout << "\n\n";
  53. cout << "************************************************************\n";
  54. cout << "** **\n";
  55. cout << "** B O O S T S O R T **\n";
  56. cout << "** S I N G L E T H R E A D **\n";
  57. cout << "** I N T E G E R B E N C H M A R K **\n";
  58. cout << "** **\n";
  59. cout << "** SORT OF 100 000 000 NUMBERS OF 64 BITS **\n";
  60. cout << "** **\n";
  61. cout << "************************************************************\n";
  62. cout << std::endl;
  63. cout<<"[ 1 ] std::sort [ 2 ] pdqsort [ 3 ] std::stable_sort \n";
  64. cout<<"[ 4 ] spinsort [ 5 ] flat_stable_sort [ 6 ] spreadsort\n\n";
  65. cout<<" | | | | | | |\n";
  66. cout<<" | [ 1 ]| [ 2 ]| [ 3 ]| [ 4 ]| [ 5 ]| [ 6 ]|\n";
  67. cout<<"--------------------+------+------+------+------+------+------+\n";
  68. std::string empty_line =
  69. " | | | | | | |\n";
  70. cout<<"random |";
  71. Generator_random ();
  72. cout<<empty_line;
  73. cout<<"sorted |";
  74. Generator_sorted ();
  75. cout<<"sorted + 0.1% end |";
  76. Generator_sorted_end (NELEM / 1000);
  77. cout<<"sorted + 1% end |";
  78. Generator_sorted_end (NELEM / 100);
  79. cout<<"sorted + 10% end |";
  80. Generator_sorted_end (NELEM / 10);
  81. cout<<empty_line;
  82. cout<<"sorted + 0.1% mid |";
  83. Generator_sorted_middle (NELEM / 1000);
  84. cout<<"sorted + 1% mid |";
  85. Generator_sorted_middle (NELEM / 100);
  86. cout<<"sorted + 10% mid |";
  87. Generator_sorted_middle (NELEM / 10);
  88. cout<<empty_line;
  89. cout<<"reverse sorted |";
  90. Generator_reverse_sorted ();
  91. cout<<"rv sorted + 0.1% end|";
  92. Generator_reverse_sorted_end (NELEM / 1000);
  93. cout<<"rv sorted + 1% end|";
  94. Generator_reverse_sorted_end (NELEM / 100);
  95. cout<<"rv sorted + 10% end|";
  96. Generator_reverse_sorted_end (NELEM / 10);
  97. cout<<empty_line;
  98. cout<<"rv sorted + 0.1% mid|";
  99. Generator_reverse_sorted_middle (NELEM / 1000);
  100. cout<<"rv sorted + 1% mid|";
  101. Generator_reverse_sorted_middle (NELEM / 100);
  102. cout<<"rv sorted + 10% mid|";
  103. Generator_reverse_sorted_middle (NELEM / 10);
  104. cout<<"--------------------+------+------+------+------+------+------+\n";
  105. cout<<endl<<endl ;
  106. return 0;
  107. }
  108. void
  109. Generator_random (void)
  110. {
  111. vector<uint64_t> A;
  112. A.reserve (NELEM);
  113. A.clear ();
  114. if (fill_vector_uint64 ("input.bin", A, NELEM) != 0)
  115. {
  116. std::cout << "Error in the input file\n";
  117. return;
  118. };
  119. Test<uint64_t, std::less<uint64_t>> (A);
  120. }
  121. ;
  122. void
  123. Generator_sorted (void)
  124. {
  125. vector<uint64_t> A;
  126. A.reserve (NELEM);
  127. A.clear ();
  128. for (size_t i = 0; i < NELEM; ++i)
  129. A.push_back (i);
  130. Test<uint64_t, std::less<uint64_t>> (A);
  131. }
  132. void Generator_sorted_end (size_t n_last)
  133. {
  134. vector<uint64_t> A;
  135. A.reserve (NELEM);
  136. A.clear ();
  137. if (fill_vector_uint64 ("input.bin", A, NELEM + n_last) != 0)
  138. {
  139. std::cout << "Error in the input file\n";
  140. return;
  141. };
  142. std::sort (A.begin (), A.begin () + NELEM);
  143. Test<uint64_t, std::less<uint64_t>> (A);
  144. }
  145. ;
  146. void Generator_sorted_middle (size_t n_last)
  147. {
  148. vector<uint64_t> A, B, C;
  149. A.reserve (NELEM);
  150. A.clear ();
  151. if (fill_vector_uint64 ("input.bin", A, NELEM + n_last) != 0)
  152. {
  153. std::cout << "Error in the input file\n";
  154. return;
  155. };
  156. for (size_t i = NELEM; i < A.size (); ++i)
  157. B.push_back (std::move (A[i]));
  158. A.resize ( NELEM);
  159. for (size_t i = 0; i < (NELEM >> 1); ++i)
  160. std::swap (A[i], A[NELEM - 1 - i]);
  161. std::sort (A.begin (), A.end ());
  162. size_t step = NELEM / n_last + 1;
  163. size_t pos = 0;
  164. for (size_t i = 0; i < B.size (); ++i, pos += step)
  165. {
  166. C.push_back (B[i]);
  167. for (size_t k = 0; k < step; ++k)
  168. C.push_back (A[pos + k]);
  169. };
  170. while (pos < A.size ())
  171. C.push_back (A[pos++]);
  172. A = C;
  173. Test<uint64_t, std::less<uint64_t>> (A);
  174. }
  175. ;
  176. void Generator_reverse_sorted (void)
  177. {
  178. vector<uint64_t> A;
  179. A.reserve (NELEM);
  180. A.clear ();
  181. for (size_t i = NELEM; i > 0; --i)
  182. A.push_back (i);
  183. Test<uint64_t, std::less<uint64_t>> (A);
  184. }
  185. void Generator_reverse_sorted_end (size_t n_last)
  186. {
  187. vector<uint64_t> A;
  188. A.reserve (NELEM);
  189. A.clear ();
  190. if (fill_vector_uint64 ("input.bin", A, NELEM + n_last) != 0)
  191. {
  192. std::cout << "Error in the input file\n";
  193. return;
  194. };
  195. std::sort (A.begin (), A.begin () + NELEM);
  196. for (size_t i = 0; i < (NELEM >> 1); ++i)
  197. std::swap (A[i], A[NELEM - 1 - i]);
  198. Test<uint64_t, std::less<uint64_t>> (A);
  199. }
  200. void Generator_reverse_sorted_middle (size_t n_last)
  201. {
  202. vector<uint64_t> A, B, C;
  203. A.reserve (NELEM);
  204. A.clear ();
  205. if (fill_vector_uint64 ("input.bin", A, NELEM + n_last) != 0)
  206. {
  207. std::cout << "Error in the input file\n";
  208. return;
  209. };
  210. for (size_t i = NELEM; i < A.size (); ++i)
  211. B.push_back (std::move (A[i]));
  212. A.resize ( NELEM);
  213. for (size_t i = 0; i < (NELEM >> 1); ++i)
  214. std::swap (A[i], A[NELEM - 1 - i]);
  215. std::sort (A.begin (), A.end ());
  216. size_t step = NELEM / n_last + 1;
  217. size_t pos = 0;
  218. for (size_t i = 0; i < B.size (); ++i, pos += step)
  219. {
  220. C.push_back (B[i]);
  221. for (size_t k = 0; k < step; ++k)
  222. C.push_back (A[pos + k]);
  223. };
  224. while (pos < A.size ())
  225. C.push_back (A[pos++]);
  226. A = C;
  227. Test<uint64_t, std::less<uint64_t>> (A);
  228. };
  229. template<class IA, class compare>
  230. int Test (std::vector<IA> &B, compare comp)
  231. { //---------------------------- begin --------------------------------
  232. double duration;
  233. time_point start, finish;
  234. std::vector<IA> A (B);
  235. std::vector<double> V;
  236. //--------------------------------------------------------------------
  237. A = B;
  238. start = now ();
  239. std::sort (A.begin (), A.end (), comp);
  240. finish = now ();
  241. duration = subtract_time (finish, start);
  242. V.push_back (duration);
  243. A = B;
  244. start = now ();
  245. pdqsort (A.begin (), A.end (), comp);
  246. finish = now ();
  247. duration = subtract_time (finish, start);
  248. V.push_back (duration);
  249. A = B;
  250. start = now ();
  251. std::stable_sort (A.begin (), A.end (), comp);
  252. finish = now ();
  253. duration = subtract_time (finish, start);
  254. V.push_back (duration);
  255. A = B;
  256. start = now ();
  257. spinsort(A.begin (), A.end (), comp);
  258. finish = now ();
  259. duration = subtract_time (finish, start);
  260. V.push_back (duration);
  261. A = B;
  262. start = now ();
  263. flat_stable_sort (A.begin (), A.end (), comp);
  264. finish = now ();
  265. duration = subtract_time (finish, start);
  266. V.push_back (duration);
  267. A = B;
  268. start = now ();
  269. spreadsort (A.begin (), A.end ());
  270. finish = now ();
  271. duration = subtract_time (finish, start);
  272. V.push_back (duration);
  273. //-----------------------------------------------------------------------
  274. // printing the vector
  275. //-----------------------------------------------------------------------
  276. std::cout<<std::setprecision(2)<<std::fixed;
  277. for ( uint32_t i =0 ; i < V.size() ; ++i)
  278. { std::cout<<std::right<<std::setw(5)<<V[i]<<" |";
  279. };
  280. std::cout<<std::endl;
  281. return 0;
  282. };