voronoi_performance.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright 2012 John Maddock. Distributed under the Boost
  3. // Software License, Version 1.0. (See accompanying file
  4. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #ifdef _MSC_VER
  6. #pragma warning(disable : 4244)
  7. #endif
  8. #include <boost/polygon/detail/voronoi_predicates.hpp>
  9. #include <boost/polygon/detail/voronoi_structures.hpp>
  10. #include <boost/polygon/detail/skeleton_predicates.hpp>
  11. #include <boost/random/mersenne_twister.hpp>
  12. #include <boost/random/uniform_int_distribution.hpp>
  13. #include <vector>
  14. #include <map>
  15. #include <boost/chrono.hpp>
  16. #include <boost/multiprecision/cpp_int.hpp>
  17. #ifdef TEST_GMP
  18. #include <boost/multiprecision/gmp.hpp>
  19. #endif
  20. #ifdef TEST_TOMMATH
  21. #include <boost/multiprecision/tommath.hpp>
  22. #endif
  23. #include "arithmetic_backend.hpp"
  24. typedef boost::polygon::detail::point_2d<boost::int32_t> i_point;
  25. template <class Clock>
  26. struct stopwatch
  27. {
  28. typedef typename Clock::duration duration;
  29. stopwatch()
  30. {
  31. m_start = Clock::now();
  32. }
  33. duration elapsed()
  34. {
  35. return Clock::now() - m_start;
  36. }
  37. void reset()
  38. {
  39. m_start = Clock::now();
  40. }
  41. private:
  42. typename Clock::time_point m_start;
  43. };
  44. std::vector<i_point> points;
  45. boost::random::mt19937 gen;
  46. template <class Big>
  47. struct cpp_int_voronoi_traits
  48. {
  49. typedef boost::int32_t int_type;
  50. typedef boost::int64_t int_x2_type;
  51. typedef boost::uint64_t uint_x2_type;
  52. typedef Big big_int_type;
  53. typedef double fpt_type;
  54. typedef boost::polygon::detail::extended_exponent_fpt<fpt_type> efpt_type;
  55. typedef boost::polygon::detail::ulp_comparison<fpt_type> ulp_cmp_type;
  56. struct to_fpt_converter_type
  57. {
  58. template <class B, boost::multiprecision::expression_template_option ET>
  59. double operator()(const boost::multiprecision::number<B, ET>& val)
  60. {
  61. return val.template convert_to<double>();
  62. }
  63. double operator()(double val)
  64. {
  65. return val;
  66. }
  67. double operator()(const efpt_type& that) const
  68. {
  69. return that.d();
  70. }
  71. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  72. double operator()(const boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e)
  73. {
  74. typedef typename boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type r_t;
  75. r_t r(e);
  76. return r.template convert_to<double>();
  77. }
  78. };
  79. struct to_efpt_converter_type
  80. {
  81. template <class B, boost::multiprecision::expression_template_option ET>
  82. efpt_type operator()(const boost::multiprecision::number<B, ET>& val)
  83. {
  84. return efpt_type(val.template convert_to<double>(), 0);
  85. }
  86. efpt_type operator()(double val)
  87. {
  88. return efpt_type(val, 0);
  89. }
  90. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
  91. double operator()(const boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& e)
  92. {
  93. typedef typename boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type r_t;
  94. r_t r(e);
  95. return efpt_type(r.template convert_to<double>(), 0);
  96. }
  97. };
  98. };
  99. template <class Big>
  100. struct native_int_voronoi_traits
  101. {
  102. typedef boost::int32_t int_type;
  103. typedef boost::int64_t int_x2_type;
  104. typedef boost::uint64_t uint_x2_type;
  105. typedef Big big_int_type;
  106. typedef double fpt_type;
  107. typedef boost::polygon::detail::extended_exponent_fpt<fpt_type> efpt_type;
  108. typedef boost::polygon::detail::ulp_comparison<fpt_type> ulp_cmp_type;
  109. struct to_fpt_converter_type
  110. {
  111. template <class T>
  112. double operator()(const T& val) const
  113. {
  114. return val;
  115. }
  116. double operator()(const efpt_type& that) const
  117. {
  118. return that.d();
  119. }
  120. };
  121. struct to_efpt_converter_type
  122. {
  123. template <class T>
  124. efpt_type operator()(const T& val) const
  125. {
  126. return efpt_type(val, 0);
  127. }
  128. };
  129. };
  130. std::map<std::string, double> results;
  131. double min_time = (std::numeric_limits<double>::max)();
  132. template <class Traits>
  133. double test(const char* name)
  134. {
  135. typedef boost::polygon::detail::voronoi_predicates<Traits> preds;
  136. typedef boost::polygon::detail::circle_event<boost::int32_t> circle_event;
  137. typedef boost::polygon::detail::site_event<boost::int32_t> site_event;
  138. typedef typename preds::template mp_circle_formation_functor<site_event, circle_event> circle_pred;
  139. boost::random::uniform_int_distribution<> dist(0, points.size() - 1);
  140. circle_pred pc;
  141. circle_event event;
  142. stopwatch<boost::chrono::high_resolution_clock> w;
  143. for (unsigned i = 0; i < 10000; ++i)
  144. {
  145. site_event s1(points[dist(gen)]);
  146. site_event s2(points[dist(gen)]);
  147. site_event s3(points[dist(gen)]);
  148. pc.ppp(s1, s2, s3, event);
  149. pc.pps(s1, s2, s3, 0, event);
  150. pc.pss(s1, s2, s3, 0, event);
  151. pc.sss(s1, s2, s3, event);
  152. }
  153. double d = boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
  154. if (d < min_time)
  155. min_time = d;
  156. results[name] = d;
  157. std::cout << "Time for " << std::setw(30) << std::left << name << " = " << d << std::endl;
  158. return d;
  159. }
  160. void generate_quickbook()
  161. {
  162. std::cout << "[table\n[[Integer Type][Relative Performance (Actual time in parenthesis)]]\n";
  163. std::map<std::string, double>::const_iterator i(results.begin()), j(results.end());
  164. while (i != j)
  165. {
  166. double rel = i->second / min_time;
  167. std::cout << "[[" << i->first << "][" << rel << "(" << i->second << "s)]]\n";
  168. ++i;
  169. }
  170. std::cout << "]\n";
  171. }
  172. int main()
  173. {
  174. boost::random::uniform_int_distribution<> dist((std::numeric_limits<boost::int32_t>::min)() / 2, (std::numeric_limits<boost::int32_t>::max)() / 2);
  175. for (unsigned i = 0; i < 100; ++i)
  176. {
  177. points.push_back(i_point(dist(gen), dist(gen)));
  178. }
  179. test<boost::polygon::detail::voronoi_ctype_traits<boost::int32_t> >("extended_int");
  180. test<cpp_int_voronoi_traits<boost::multiprecision::int256_t> >("int256_t");
  181. test<cpp_int_voronoi_traits<boost::multiprecision::int512_t> >("int512_t");
  182. test<cpp_int_voronoi_traits<boost::multiprecision::int1024_t> >("int1024_t");
  183. test<cpp_int_voronoi_traits<boost::multiprecision::checked_int256_t> >("checked_int256_t");
  184. test<cpp_int_voronoi_traits<boost::multiprecision::checked_int512_t> >("checked_int512_t");
  185. test<cpp_int_voronoi_traits<boost::multiprecision::checked_int1024_t> >("checked_int1024_t");
  186. test<cpp_int_voronoi_traits<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<>, boost::multiprecision::et_off> > >("cpp_int");
  187. #ifdef TEST_GMP
  188. test<cpp_int_voronoi_traits<boost::multiprecision::number<boost::multiprecision::gmp_int, boost::multiprecision::et_off> > >("mpz_int");
  189. #endif
  190. #ifdef TEST_TOMMATH
  191. test<cpp_int_voronoi_traits<boost::multiprecision::number<boost::multiprecision::tommath_int, boost::multiprecision::et_off> > >("tom_int");
  192. #endif
  193. generate_quickbook();
  194. test<native_int_voronoi_traits<boost::int64_t> >("int64_t");
  195. test<cpp_int_voronoi_traits<boost::multiprecision::number<boost::multiprecision::arithmetic_backend<boost::int64_t>, boost::multiprecision::et_off> > >("number<arithmetic_backend<boost::int64_t>, et_off>");
  196. //test<cpp_int_voronoi_traits<boost::multiprecision::number<boost::multiprecision::arithmetic_backend<boost::int64_t>, boost::multiprecision::et_on> > >("number<arithmetic_backend<boost::int64_t>, et_on>");
  197. return 0;
  198. }