test_polynomial.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. ///////////////////////////////////////////////////////////////
  2. // Copyright 2017 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_
  5. #define BOOST_CHRONO_HEADER_ONLY
  6. #ifdef _MSC_VER
  7. # define _SCL_SECURE_NO_WARNINGS
  8. #endif
  9. #include "performance.hpp"
  10. #include "table_helper.hpp"
  11. #include <boost/random.hpp>
  12. #include <boost/math/tools/polynomial.hpp>
  13. #include <boost/multiprecision/cpp_int.hpp>
  14. unsigned max_reps = 1000;
  15. template <class T>
  16. struct tester
  17. {
  18. tester()
  19. {
  20. a.assign(500, T());
  21. for(int i = 0; i < 500; ++i)
  22. {
  23. b.push_back(generate_random(false));
  24. c.push_back(generate_random(false));
  25. small.push_back(generate_random(true));
  26. }
  27. }
  28. double test_add()
  29. {
  30. stopwatch<boost::chrono::high_resolution_clock> w;
  31. for (unsigned repeats = 0; repeats < max_reps; ++repeats)
  32. {
  33. for(unsigned i = 0; i < b.size(); ++i)
  34. a[i] = b[i] + c[i];
  35. }
  36. return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
  37. }
  38. double test_subtract()
  39. {
  40. stopwatch<boost::chrono::high_resolution_clock> w;
  41. for (unsigned repeats = 0; repeats < max_reps; ++repeats)
  42. {
  43. for(unsigned i = 0; i < b.size(); ++i)
  44. a[i] = b[i] - c[i];
  45. }
  46. return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
  47. }
  48. double test_add_int()
  49. {
  50. stopwatch<boost::chrono::high_resolution_clock> w;
  51. for (unsigned repeats = 0; repeats < max_reps; ++repeats)
  52. {
  53. for(unsigned i = 0; i < b.size(); ++i)
  54. a[i] = b[i] + 1;
  55. }
  56. return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
  57. }
  58. double test_subtract_int()
  59. {
  60. stopwatch<boost::chrono::high_resolution_clock> w;
  61. for (unsigned repeats = 0; repeats < max_reps; ++repeats)
  62. {
  63. for(unsigned i = 0; i < b.size(); ++i)
  64. a[i] = b[i] - 1;
  65. }
  66. return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
  67. }
  68. double test_multiply()
  69. {
  70. stopwatch<boost::chrono::high_resolution_clock> w;
  71. for (unsigned repeats = 0; repeats < max_reps; ++repeats)
  72. {
  73. for(unsigned k = 0; k < b.size(); ++k)
  74. a[k] = b[k] * c[k];
  75. }
  76. return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
  77. }
  78. double test_multiply_int()
  79. {
  80. stopwatch<boost::chrono::high_resolution_clock> w;
  81. for (unsigned repeats = 0; repeats < max_reps; ++repeats)
  82. {
  83. for(unsigned i = 0; i < b.size(); ++i)
  84. a[i] = b[i] * 3;
  85. }
  86. return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
  87. }
  88. double test_divide()
  89. {
  90. stopwatch<boost::chrono::high_resolution_clock> w;
  91. for (unsigned repeats = 0; repeats < max_reps; ++repeats)
  92. {
  93. for(unsigned i = 0; i < b.size(); ++i)
  94. a[i] = b[i] / small[i];
  95. }
  96. return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
  97. }
  98. double test_divide_int()
  99. {
  100. stopwatch<boost::chrono::high_resolution_clock> w;
  101. for (unsigned repeats = 0; repeats < max_reps; ++repeats)
  102. {
  103. for(unsigned i = 0; i < b.size(); ++i)
  104. a[i] = b[i] / 3;
  105. }
  106. return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
  107. }
  108. double test_gcd()
  109. {
  110. using boost::integer::gcd;
  111. stopwatch<boost::chrono::high_resolution_clock> w;
  112. for (unsigned repeats = 0; repeats < max_reps; ++repeats)
  113. {
  114. for(unsigned i = 0; i < b.size(); ++i)
  115. a[i] = gcd(b[i], c[i]);
  116. }
  117. return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
  118. }
  119. double test_inplace_add()
  120. {
  121. stopwatch<boost::chrono::high_resolution_clock> w;
  122. for (unsigned repeats = 0; repeats < max_reps; ++repeats)
  123. {
  124. for (unsigned i = 0; i < b.size(); ++i)
  125. b[i] += c[i];
  126. }
  127. return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
  128. }
  129. double test_inplace_subtract()
  130. {
  131. stopwatch<boost::chrono::high_resolution_clock> w;
  132. for (unsigned repeats = 0; repeats < max_reps; ++repeats)
  133. {
  134. for (unsigned i = 0; i < b.size(); ++i)
  135. b[i] -= c[i];
  136. }
  137. return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
  138. }
  139. double test_inplace_add_int()
  140. {
  141. stopwatch<boost::chrono::high_resolution_clock> w;
  142. for (unsigned repeats = 0; repeats < max_reps; ++repeats)
  143. {
  144. for (unsigned i = 0; i < b.size(); ++i)
  145. b[i] += 1;
  146. }
  147. return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
  148. }
  149. double test_inplace_subtract_int()
  150. {
  151. stopwatch<boost::chrono::high_resolution_clock> w;
  152. for (unsigned repeats = 0; repeats < max_reps; ++repeats)
  153. {
  154. for (unsigned i = 0; i < b.size(); ++i)
  155. b[i] -= 1;
  156. }
  157. return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
  158. }
  159. double test_inplace_multiply()
  160. {
  161. stopwatch<boost::chrono::high_resolution_clock> w;
  162. for (unsigned repeats = 0; repeats < max_reps; ++repeats)
  163. {
  164. for (unsigned k = 0; k < b.size(); ++k)
  165. b[k] *= c[k];
  166. }
  167. return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
  168. }
  169. double test_inplace_multiply_int()
  170. {
  171. stopwatch<boost::chrono::high_resolution_clock> w;
  172. for (unsigned repeats = 0; repeats < max_reps; ++repeats)
  173. {
  174. for (unsigned i = 0; i < b.size(); ++i)
  175. b[i] *= 3;
  176. }
  177. return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
  178. }
  179. double test_inplace_divide()
  180. {
  181. stopwatch<boost::chrono::high_resolution_clock> w;
  182. for (unsigned repeats = 0; repeats < max_reps; ++repeats)
  183. {
  184. for (unsigned i = 0; i < b.size(); ++i)
  185. a[i] /= small[i];
  186. }
  187. return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
  188. }
  189. double test_inplace_divide_int()
  190. {
  191. stopwatch<boost::chrono::high_resolution_clock> w;
  192. for (unsigned repeats = 0; repeats < max_reps; ++repeats)
  193. {
  194. for (unsigned i = 0; i < b.size(); ++i)
  195. b[i] /= 3;
  196. }
  197. return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
  198. }
  199. private:
  200. T generate_random(bool issmall)
  201. {
  202. boost::uniform_int<> ui(2, issmall ? 5 : 40), ui2(1, 10000);
  203. std::size_t len = ui(gen);
  204. std::vector<typename T::value_type> values;
  205. for (std::size_t i = 0; i < len; ++i)
  206. {
  207. values.push_back(static_cast<typename T::value_type>(ui2(gen)));
  208. }
  209. return T(values.begin(), values.end());
  210. }
  211. std::vector<T> a, b, c, small;
  212. static boost::random::mt19937 gen;
  213. };
  214. template <class N>
  215. boost::random::mt19937 tester<N>::gen;
  216. template <class Number>
  217. void test(const char* type)
  218. {
  219. std::cout << "Testing type: " << type << std::endl;
  220. tester<boost::math::tools::polynomial<Number> > t;
  221. int count = 500 * max_reps;
  222. std::string table_name = "Polynomial Arithmetic (" + compiler_name() + ", " + platform_name() + ")";
  223. //
  224. // Now the actual tests:
  225. //
  226. report_execution_time(t.test_add() / count, table_name, "operator +", type);
  227. report_execution_time(t.test_subtract() / count, table_name, "operator -", type);
  228. report_execution_time(t.test_multiply() / count, table_name, "operator *", type);
  229. report_execution_time(t.test_divide() / count, table_name, "operator /", type);
  230. report_execution_time(t.test_add_int() / count, table_name, "operator + (int)", type);
  231. report_execution_time(t.test_subtract_int() / count, table_name, "operator - (int)", type);
  232. report_execution_time(t.test_multiply_int() / count, table_name, "operator * (int)", type);
  233. report_execution_time(t.test_divide_int() / count, table_name, "operator / (int)", type);
  234. report_execution_time(t.test_inplace_add() / count, table_name, "operator +=", type);
  235. report_execution_time(t.test_inplace_subtract() / count, table_name, "operator -=", type);
  236. report_execution_time(t.test_inplace_multiply() / count, table_name, "operator *=", type);
  237. report_execution_time(t.test_inplace_divide() / count, table_name, "operator /=", type);
  238. report_execution_time(t.test_inplace_add_int() / count, table_name, "operator += (int)", type);
  239. report_execution_time(t.test_inplace_subtract_int() / count, table_name, "operator -= (int)", type);
  240. report_execution_time(t.test_inplace_multiply_int() / count, table_name, "operator *= (int)", type);
  241. report_execution_time(t.test_inplace_divide_int() / count, table_name, "operator /= (int)", type);
  242. //report_execution_time(t.test_gcd() / count, table_name, "gcd", type);
  243. }
  244. int main()
  245. {
  246. test<boost::uint64_t>("boost::uint64_t");
  247. test<double>("double");
  248. max_reps = 100;
  249. test<boost::multiprecision::cpp_int>("cpp_int");
  250. return 0;
  251. }