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