1 // Copyright 2016-2021 Francesco Biscani (bluescarni@gmail.com)
2 //
3 // This file is part of the mp++ library.
4 //
5 // This Source Code Form is subject to the terms of the Mozilla
6 // Public License v. 2.0. If a copy of the MPL was not distributed
7 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
9 #include <algorithm>
10 #include <cstdint>
11 #include <numeric>
12 #include <random>
13 #include <vector>
14
15 #if defined(MPPP_BENCHMARK_BOOST)
16
17 #include <boost/multiprecision/cpp_int.hpp>
18 #include <boost/multiprecision/gmp.hpp>
19
20 #endif
21
22 #if defined(MPPP_BENCHMARK_FLINT)
23
24 #include <flint/flint.h>
25 #include <flint/fmpzxx.h>
26
27 #endif
28
29 #include <fmt/core.h>
30 #include <fmt/ostream.h>
31
32 #include <mp++/integer.hpp>
33
34 #if defined(MPPP_BENCHMARK_BOOST)
35
36 #include <mp++/detail/gmp.hpp>
37
38 #endif
39
40 #include "utils.hpp"
41
42 namespace
43 {
44
45 #if defined(MPPP_BENCHMARK_BOOST)
46
47 using cpp_int = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<>, boost::multiprecision::et_on>;
48 using mpz_int = boost::multiprecision::number<boost::multiprecision::gmp_int, boost::multiprecision::et_off>;
49
50 #endif
51
52 std::mt19937 rng;
53
54 constexpr auto size = 30000000ul;
55
56 template <typename T>
get_init_vector()57 std::vector<T> get_init_vector()
58 {
59 rng.seed(0);
60 std::uniform_int_distribution<unsigned> dist(0u, 10000u);
61 std::vector<T> retval(size);
62 std::generate(retval.begin(), retval.end(), [&dist]() { return T(dist(rng)); });
63 return retval;
64 }
65
66 const auto benchmark_name = mppp_benchmark_name();
67
68 } // namespace
69
main()70 int main()
71 {
72 fmt::print("Benchmark name: {}\n", benchmark_name);
73
74 // Warm up.
75 mppp_benchmark::warmup();
76
77 // Prepare the benchmark result data.
78 mppp_benchmark::data_t bdata;
79
80 {
81 auto v = get_init_vector<mppp::integer<2>>();
82 constexpr auto name = "mppp::integer<2>";
83
84 std::vector<unsigned> c_out(size);
85
86 mppp_benchmark::simple_timer st;
87
88 std::transform(v.begin(), v.end(), c_out.begin(),
89 [](const mppp::integer<2> &n) { return static_cast<unsigned>(n); });
90
91 const auto runtime = st.elapsed();
92 bdata.emplace_back(name, runtime);
93 fmt::print(mppp_benchmark::res_print_format, name, runtime, std::accumulate(c_out.begin(), c_out.end(), 0ul));
94 }
95
96 #if defined(MPPP_BENCHMARK_BOOST)
97 {
98 auto v = get_init_vector<cpp_int>();
99 constexpr auto name = "boost::cpp_int";
100
101 std::vector<unsigned> c_out(size);
102
103 mppp_benchmark::simple_timer st;
104
105 std::transform(v.begin(), v.end(), c_out.begin(), [](const cpp_int &n) { return static_cast<unsigned>(n); });
106
107 const auto runtime = st.elapsed();
108 bdata.emplace_back(name, runtime);
109 fmt::print(mppp_benchmark::res_print_format, name, runtime, std::accumulate(c_out.begin(), c_out.end(), 0ul));
110 }
111
112 {
113 auto v = get_init_vector<mpz_int>();
114 constexpr auto name = "boost::gmp_int";
115
116 std::vector<unsigned> c_out(size);
117
118 mppp_benchmark::simple_timer st;
119
120 std::transform(v.begin(), v.end(), c_out.begin(),
121 [](const mpz_int &n) { return static_cast<unsigned>(mpz_get_ui(n.backend().data())); });
122
123 const auto runtime = st.elapsed();
124 bdata.emplace_back(name, runtime);
125 fmt::print(mppp_benchmark::res_print_format, name, runtime, std::accumulate(c_out.begin(), c_out.end(), 0ul));
126 }
127 #endif
128
129 #if defined(MPPP_BENCHMARK_FLINT)
130 {
131 auto v = get_init_vector<flint::fmpzxx>();
132 constexpr auto name = "flint::fmpzxx";
133
134 std::vector<unsigned> c_out(size);
135
136 mppp_benchmark::simple_timer st;
137
138 std::transform(v.begin(), v.end(), c_out.begin(),
139 [](const flint::fmpzxx &n) { return static_cast<unsigned>(::fmpz_get_ui(n._data().inner)); });
140
141 const auto runtime = st.elapsed();
142 bdata.emplace_back(name, runtime);
143 fmt::print(mppp_benchmark::res_print_format, name, runtime, std::accumulate(c_out.begin(), c_out.end(), 0ul));
144 }
145 #endif
146
147 // Write out the .py and .rst files.
148 mppp_benchmark::write_out(bdata, benchmark_name);
149 }
150