123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- ///////////////////////////////////////////////////////////////
- // Copyright 2017 John Maddock. Distributed under the Boost
- // Software License, Version 1.0. (See accompanying file
- // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_
- #define BOOST_CHRONO_HEADER_ONLY
- #ifdef _MSC_VER
- # define _SCL_SECURE_NO_WARNINGS
- #endif
- #include "performance.hpp"
- #include "table_helper.hpp"
- #include <boost/random.hpp>
- #include <boost/math/tools/polynomial.hpp>
- #include <boost/multiprecision/cpp_int.hpp>
- unsigned max_reps = 1000;
- template <class T>
- struct tester
- {
- tester()
- {
- a.assign(500, T());
- for(int i = 0; i < 500; ++i)
- {
- b.push_back(generate_random(false));
- c.push_back(generate_random(false));
- small.push_back(generate_random(true));
- }
- }
- double test_add()
- {
- stopwatch<boost::chrono::high_resolution_clock> w;
- for (unsigned repeats = 0; repeats < max_reps; ++repeats)
- {
- for(unsigned i = 0; i < b.size(); ++i)
- a[i] = b[i] + c[i];
- }
- return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
- }
- double test_subtract()
- {
- stopwatch<boost::chrono::high_resolution_clock> w;
- for (unsigned repeats = 0; repeats < max_reps; ++repeats)
- {
- for(unsigned i = 0; i < b.size(); ++i)
- a[i] = b[i] - c[i];
- }
- return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
- }
- double test_add_int()
- {
- stopwatch<boost::chrono::high_resolution_clock> w;
- for (unsigned repeats = 0; repeats < max_reps; ++repeats)
- {
- for(unsigned i = 0; i < b.size(); ++i)
- a[i] = b[i] + 1;
- }
- return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
- }
- double test_subtract_int()
- {
- stopwatch<boost::chrono::high_resolution_clock> w;
- for (unsigned repeats = 0; repeats < max_reps; ++repeats)
- {
- for(unsigned i = 0; i < b.size(); ++i)
- a[i] = b[i] - 1;
- }
- return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
- }
- double test_multiply()
- {
- stopwatch<boost::chrono::high_resolution_clock> w;
- for (unsigned repeats = 0; repeats < max_reps; ++repeats)
- {
- for(unsigned k = 0; k < b.size(); ++k)
- a[k] = b[k] * c[k];
- }
- return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
- }
- double test_multiply_int()
- {
- stopwatch<boost::chrono::high_resolution_clock> w;
- for (unsigned repeats = 0; repeats < max_reps; ++repeats)
- {
- for(unsigned i = 0; i < b.size(); ++i)
- a[i] = b[i] * 3;
- }
- return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
- }
- double test_divide()
- {
- stopwatch<boost::chrono::high_resolution_clock> w;
- for (unsigned repeats = 0; repeats < max_reps; ++repeats)
- {
- for(unsigned i = 0; i < b.size(); ++i)
- a[i] = b[i] / small[i];
- }
- return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
- }
- double test_divide_int()
- {
- stopwatch<boost::chrono::high_resolution_clock> w;
- for (unsigned repeats = 0; repeats < max_reps; ++repeats)
- {
- for(unsigned i = 0; i < b.size(); ++i)
- a[i] = b[i] / 3;
- }
- return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
- }
- double test_gcd()
- {
- using boost::integer::gcd;
- stopwatch<boost::chrono::high_resolution_clock> w;
- for (unsigned repeats = 0; repeats < max_reps; ++repeats)
- {
- for(unsigned i = 0; i < b.size(); ++i)
- a[i] = gcd(b[i], c[i]);
- }
- return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
- }
- double test_inplace_add()
- {
- stopwatch<boost::chrono::high_resolution_clock> w;
- for (unsigned repeats = 0; repeats < max_reps; ++repeats)
- {
- for (unsigned i = 0; i < b.size(); ++i)
- b[i] += c[i];
- }
- return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
- }
- double test_inplace_subtract()
- {
- stopwatch<boost::chrono::high_resolution_clock> w;
- for (unsigned repeats = 0; repeats < max_reps; ++repeats)
- {
- for (unsigned i = 0; i < b.size(); ++i)
- b[i] -= c[i];
- }
- return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
- }
- double test_inplace_add_int()
- {
- stopwatch<boost::chrono::high_resolution_clock> w;
- for (unsigned repeats = 0; repeats < max_reps; ++repeats)
- {
- for (unsigned i = 0; i < b.size(); ++i)
- b[i] += 1;
- }
- return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
- }
- double test_inplace_subtract_int()
- {
- stopwatch<boost::chrono::high_resolution_clock> w;
- for (unsigned repeats = 0; repeats < max_reps; ++repeats)
- {
- for (unsigned i = 0; i < b.size(); ++i)
- b[i] -= 1;
- }
- return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
- }
- double test_inplace_multiply()
- {
- stopwatch<boost::chrono::high_resolution_clock> w;
- for (unsigned repeats = 0; repeats < max_reps; ++repeats)
- {
- for (unsigned k = 0; k < b.size(); ++k)
- b[k] *= c[k];
- }
- return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
- }
- double test_inplace_multiply_int()
- {
- stopwatch<boost::chrono::high_resolution_clock> w;
- for (unsigned repeats = 0; repeats < max_reps; ++repeats)
- {
- for (unsigned i = 0; i < b.size(); ++i)
- b[i] *= 3;
- }
- return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
- }
- double test_inplace_divide()
- {
- stopwatch<boost::chrono::high_resolution_clock> w;
- for (unsigned repeats = 0; repeats < max_reps; ++repeats)
- {
- for (unsigned i = 0; i < b.size(); ++i)
- a[i] /= small[i];
- }
- return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
- }
- double test_inplace_divide_int()
- {
- stopwatch<boost::chrono::high_resolution_clock> w;
- for (unsigned repeats = 0; repeats < max_reps; ++repeats)
- {
- for (unsigned i = 0; i < b.size(); ++i)
- b[i] /= 3;
- }
- return boost::chrono::duration_cast<boost::chrono::duration<double> >(w.elapsed()).count();
- }
- private:
- T generate_random(bool issmall)
- {
- boost::uniform_int<> ui(2, issmall ? 5 : 40), ui2(1, 10000);
- std::size_t len = ui(gen);
- std::vector<typename T::value_type> values;
- for (std::size_t i = 0; i < len; ++i)
- {
- values.push_back(static_cast<typename T::value_type>(ui2(gen)));
- }
- return T(values.begin(), values.end());
- }
- std::vector<T> a, b, c, small;
- static boost::random::mt19937 gen;
- };
- template <class N>
- boost::random::mt19937 tester<N>::gen;
- template <class Number>
- void test(const char* type)
- {
- std::cout << "Testing type: " << type << std::endl;
- tester<boost::math::tools::polynomial<Number> > t;
- int count = 500 * max_reps;
- std::string table_name = "Polynomial Arithmetic (" + compiler_name() + ", " + platform_name() + ")";
- //
- // Now the actual tests:
- //
- report_execution_time(t.test_add() / count, table_name, "operator +", type);
- report_execution_time(t.test_subtract() / count, table_name, "operator -", type);
- report_execution_time(t.test_multiply() / count, table_name, "operator *", type);
- report_execution_time(t.test_divide() / count, table_name, "operator /", type);
- report_execution_time(t.test_add_int() / count, table_name, "operator + (int)", type);
- report_execution_time(t.test_subtract_int() / count, table_name, "operator - (int)", type);
- report_execution_time(t.test_multiply_int() / count, table_name, "operator * (int)", type);
- report_execution_time(t.test_divide_int() / count, table_name, "operator / (int)", type);
- report_execution_time(t.test_inplace_add() / count, table_name, "operator +=", type);
- report_execution_time(t.test_inplace_subtract() / count, table_name, "operator -=", type);
- report_execution_time(t.test_inplace_multiply() / count, table_name, "operator *=", type);
- report_execution_time(t.test_inplace_divide() / count, table_name, "operator /=", type);
- report_execution_time(t.test_inplace_add_int() / count, table_name, "operator += (int)", type);
- report_execution_time(t.test_inplace_subtract_int() / count, table_name, "operator -= (int)", type);
- report_execution_time(t.test_inplace_multiply_int() / count, table_name, "operator *= (int)", type);
- report_execution_time(t.test_inplace_divide_int() / count, table_name, "operator /= (int)", type);
- //report_execution_time(t.test_gcd() / count, table_name, "gcd", type);
- }
- int main()
- {
- test<boost::uint64_t>("boost::uint64_t");
- test<double>("double");
- max_reps = 100;
- test<boost::multiprecision::cpp_int>("cpp_int");
- return 0;
- }
|