test_performance.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // test performance.cpp : Defines the entry point for the console application.
  2. //
  3. #include <cstdio>
  4. #include <cstdint>
  5. #include <iostream>
  6. #include <chrono>
  7. #include <boost/multiprecision/cpp_int.hpp>
  8. #include <boost/multiprecision/integer.hpp>
  9. #include <boost/safe_numerics/safe_integer.hpp>
  10. typedef boost::safe_numerics::safe<unsigned> safe_type;
  11. namespace boost {
  12. namespace multiprecision {
  13. template <class Integer, class I2>
  14. typename enable_if_c<boost::safe_numerics::is_safe<Integer>::value, Integer&>::type
  15. multiply(Integer& result, const I2& a, const I2& b){
  16. return result = static_cast<Integer>(a) * static_cast<Integer>(b);
  17. }
  18. template <class Integer>
  19. typename enable_if_c<boost::safe_numerics::is_safe<Integer>::value, bool>::type
  20. bit_test(const Integer& val, unsigned index){
  21. Integer mask = 1;
  22. if (index >= sizeof(Integer) * CHAR_BIT)
  23. return 0;
  24. if (index)
  25. mask <<= index;
  26. return val & mask ? true : false;
  27. }
  28. template <class I1, class I2>
  29. typename enable_if_c<boost::safe_numerics::is_safe<I1>::value, I2>::type
  30. integer_modulus(const I1& x, I2 val){
  31. return x % val;
  32. }
  33. namespace detail {
  34. template <class T> struct double_integer;
  35. template <>
  36. struct double_integer<safe_type>{
  37. using type = boost::safe_numerics::safe<std::uint64_t>;
  38. };
  39. }
  40. template <class I1, class I2, class I3>
  41. typename enable_if_c<boost::safe_numerics::is_safe<I1>::value, I1>::type
  42. powm(const I1& a, I2 b, I3 c){
  43. typedef typename detail::double_integer<I1>::type double_type;
  44. I1 x(1), y(a);
  45. double_type result;
  46. while (b > 0){
  47. if (b & 1){
  48. multiply(result, x, y);
  49. x = integer_modulus(result, c);
  50. }
  51. multiply(result, y, y);
  52. y = integer_modulus(result, c);
  53. b >>= 1;
  54. }
  55. return x % c;
  56. }
  57. template <class T, class PP, class EP>
  58. inline unsigned
  59. lsb(const boost::safe_numerics::safe<T, PP, EP>& x){
  60. return lsb(static_cast<T>(x));
  61. }
  62. } }
  63. #include <boost/multiprecision/miller_rabin.hpp>
  64. template <class Clock>
  65. class stopwatch
  66. {
  67. const typename Clock::time_point m_start;
  68. public:
  69. stopwatch() :
  70. m_start(Clock::now())
  71. {}
  72. typename Clock::duration elapsed() const {
  73. return Clock::now() - m_start;
  74. }
  75. };
  76. template<typename T>
  77. void test(const char * msg){
  78. const stopwatch<std::chrono::high_resolution_clock> c;
  79. unsigned count = 0;
  80. for (T i = 3; i < 30000000; ++i)
  81. if (boost::multiprecision::miller_rabin_test(i, 25)) ++count;
  82. std::chrono::duration<double> time = c.elapsed();
  83. std::cout<< msg << ":\ntime = " << time.count();
  84. std::cout << "\ncount = " << count << std::endl;
  85. }
  86. int main()
  87. {
  88. test<unsigned>("Testing type unsigned");
  89. test<boost::safe_numerics::safe<unsigned>>("Testing type safe<unsigned>");
  90. return 0;
  91. }