tree_perf_test.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2007-2013
  4. //
  5. // Distributed under the Boost Software License, Version 1.0.
  6. // (See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // See http://www.boost.org/libs/intrusive for documentation.
  10. //
  11. /////////////////////////////////////////////////////////////////////////////
  12. //Includes for tests
  13. #include <boost/intrusive/detail/config_begin.hpp>
  14. #include <boost/config.hpp>
  15. #include <iostream>
  16. #include <vector>
  17. #include <boost/intrusive/set.hpp>
  18. #include <boost/intrusive/sg_set.hpp>
  19. #include <boost/intrusive/avl_set.hpp>
  20. #include <boost/date_time/posix_time/posix_time.hpp>
  21. #include <cstdlib>
  22. using namespace boost::posix_time;
  23. using namespace boost::intrusive;
  24. template<bool BigSize> struct filler { int dummy[10]; };
  25. template <> struct filler<false> {};
  26. template<bool BigSize> //The object for non-intrusive containers
  27. struct test_class : private filler<BigSize>
  28. {
  29. std::size_t i_;
  30. friend bool operator <(const test_class &l, const test_class &r) { return l.i_ < r.i_; }
  31. friend bool operator >(const test_class &l, const test_class &r) { return l.i_ > r.i_; }
  32. };
  33. template <bool BigSize, class HookType>
  34. struct itest_class //The object for intrusive containers
  35. : public HookType, public test_class<BigSize>
  36. {
  37. };
  38. #ifdef NDEBUG
  39. const std::size_t NumElem = 1000000;
  40. #else
  41. const std::size_t NumElem = 10000;
  42. #endif
  43. const std::size_t NumRepeat = 4;
  44. enum InsertionType
  45. {
  46. Monotonic,
  47. Random
  48. };
  49. template<class Container>
  50. void fill_vector(Container &values, InsertionType insertion_type)
  51. {
  52. switch(insertion_type){
  53. case Monotonic:{
  54. for( typename Container::size_type i = 0, max = values.size()
  55. ; i != max
  56. ; ++i){
  57. values[i].i_ = i;
  58. }
  59. }
  60. break;
  61. case Random:{
  62. std::srand(0);
  63. for( typename Container::size_type i = 0, max = values.size()
  64. ; i != max
  65. ; ++i){
  66. values[i].i_ = i;
  67. }
  68. std::random_shuffle(values.begin(), values.end());
  69. }
  70. break;
  71. default:{
  72. std::abort();
  73. }
  74. }
  75. }
  76. template<class Container>
  77. void test_insertion(Container &c, const char *ContainerName, InsertionType insertion_type)
  78. {
  79. std::cout << "Container " << ContainerName << std::endl;
  80. //Prepare
  81. typedef typename Container::size_type size_type;
  82. typedef typename Container::value_type value_type;
  83. ptime tini, tend;
  84. std::vector<Container::value_type> values(NumElem);
  85. {
  86. fill_vector(values, insertion_type);
  87. //Insert
  88. tini = microsec_clock::universal_time();
  89. for( size_type repeat = 0, repeat_max = NumRepeat
  90. ; repeat != repeat_max
  91. ; ++repeat){
  92. c.clear();
  93. for( size_type i = 0, max = values.size()
  94. ; i != max
  95. ; ++i){
  96. c.insert(values[i]);
  97. }
  98. if(c.size() != values.size()){
  99. std::cout << " ERROR: size not consistent" << std::endl;
  100. }
  101. }
  102. tend = microsec_clock::universal_time();
  103. std::cout << " Insert ns/iter: " << double((tend-tini).total_nanoseconds())/double(NumElem*NumRepeat) << std::endl;
  104. }
  105. //Search
  106. {
  107. value_type v;
  108. tini = microsec_clock::universal_time();
  109. for( size_type repeat = 0, repeat_max = NumRepeat
  110. ; repeat != repeat_max
  111. ; ++repeat){
  112. size_type found = 0;
  113. for( size_type i = 0, max = values.size()
  114. ; i != max
  115. ; ++i){
  116. v.i_ = i;
  117. found += static_cast<size_type>(c.end() != c.find(v));
  118. }
  119. if(found != NumElem){
  120. std::cout << " ERROR: all not found (" << found << ") vs. (" << NumElem << ")" << std::endl;
  121. }
  122. }
  123. tend = microsec_clock::universal_time();
  124. std::cout << " Search ns/iter: " << double((tend-tini).total_nanoseconds())/double(NumElem*NumRepeat) << std::endl;
  125. }
  126. }
  127. void test_insert_search(InsertionType insertion_type)
  128. {
  129. {
  130. typedef set_base_hook< link_mode<normal_link> > SetHook;
  131. typedef set< itest_class<true, SetHook> > Set;
  132. Set c;
  133. test_insertion(c, "Set", insertion_type);
  134. }
  135. {
  136. typedef avl_set_base_hook< link_mode<normal_link> > AvlSetHook;
  137. typedef avl_set< itest_class<true, AvlSetHook> > AvlSet;
  138. AvlSet c;
  139. test_insertion(c, "AvlSet", insertion_type);
  140. }
  141. {
  142. typedef bs_set_base_hook< link_mode<normal_link> > BsSetHook;
  143. typedef sg_set< itest_class<true, BsSetHook> > SgSet;
  144. SgSet c;
  145. c.balance_factor(0.55f);
  146. test_insertion(c, "SgSet(alpha 0.55)", insertion_type);
  147. }
  148. {
  149. typedef bs_set_base_hook< link_mode<normal_link> > BsSetHook;
  150. typedef sg_set< itest_class<true, BsSetHook> > SgSet;
  151. SgSet c;
  152. c.balance_factor(0.60f);
  153. test_insertion(c, "SgSet(alpha 0.60)", insertion_type);
  154. }
  155. {
  156. typedef bs_set_base_hook< link_mode<normal_link> > BsSetHook;
  157. typedef sg_set< itest_class<true, BsSetHook> > SgSet;
  158. SgSet c;
  159. c.balance_factor(0.65f);
  160. test_insertion(c, "SgSet(alpha 0.65)", insertion_type);
  161. }
  162. {
  163. typedef bs_set_base_hook< link_mode<normal_link> > BsSetHook;
  164. typedef sg_set< itest_class<true, BsSetHook> > SgSet;
  165. SgSet c;
  166. test_insertion(c, "SgSet(alpha 0.7)", insertion_type);
  167. }
  168. {
  169. typedef bs_set_base_hook< link_mode<normal_link> > BsSetHook;
  170. typedef sg_set< itest_class<true, BsSetHook> > SgSet;
  171. SgSet c;
  172. c.balance_factor(0.75f);
  173. test_insertion(c, "SgSet(alpha 0.75)", insertion_type);
  174. }
  175. {
  176. typedef bs_set_base_hook< link_mode<normal_link> > BsSetHook;
  177. typedef sg_set< itest_class<true, BsSetHook> > SgSet;
  178. SgSet c;
  179. c.balance_factor(0.80f);
  180. test_insertion(c, "SgSet(alpha 0.80)", insertion_type);
  181. }
  182. {
  183. typedef bs_set_base_hook< link_mode<normal_link> > BsSetHook;
  184. typedef sg_set< itest_class<true, BsSetHook>, floating_point<false> > SgSet;
  185. SgSet c;
  186. test_insertion(c, "SgSet(no float, alpha 1/sqrt(2)~0,7071)", insertion_type);
  187. }
  188. }
  189. int main()
  190. {
  191. std::cout << "MONOTONIC INPUTS\n";
  192. std::cout << "----------------\n\n";
  193. test_insert_search(Monotonic);
  194. std::cout << "----------------\n\n";
  195. std::cout << "RANDOM INPUTS\n";
  196. std::cout << "----------------\n\n";
  197. test_insert_search(Random);
  198. std::cout << "----------------\n\n";
  199. return 0;
  200. }
  201. #include <boost/intrusive/detail/config_end.hpp>