]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/uuid/test/test_bench_random.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / uuid / test / test_bench_random.cpp
CommitLineData
11fdf7f2 1//
92f5a8d4 2// Copyright (c) 2017, 2018 James E. King III
11fdf7f2
TL
3//
4// Distributed under the Boost Software License, Version 1.0.
5// (See accompanying file LICENSE_1_0.txt or copy at
92f5a8d4 6// https://www.boost.org/LICENSE_1_0.txt)
11fdf7f2
TL
7//
8// benchmark for random_generators in different forms
9//
10
11#include <boost/core/ignore_unused.hpp>
12#include <boost/timer/timer.hpp>
13#include <boost/predef/os.h>
14#include <boost/uuid/random_generator.hpp>
15#include <boost/uuid/uuid.hpp>
16#include <boost/uuid/uuid_io.hpp>
17#include <iostream>
18#include <limits>
19
92f5a8d4
TL
20#if !defined(BOOST_NO_STRESS_TEST)
21// must be a Valgrind, UBsan, or other stressful job
11fdf7f2
TL
22#define AVG_LOOPS 1
23#define GEN_LOOPS 10
24#define REUSE_LOOPS 100
25#else
26#define AVG_LOOPS 10
27#define GEN_LOOPS 10000
28#define REUSE_LOOPS 1000000
29#endif
30
31template<class Generator>
32void auto_timed_generator_ctordtor(size_t count)
33{
34 boost::timer::auto_cpu_timer t;
35 for (size_t i = 0; i < count; ++i)
36 {
37 Generator gen;
38 boost::ignore_unused(gen);
39 }
40}
41
42template<class Generator>
43void auto_timed_generator_novel(size_t count)
44{
45 boost::timer::auto_cpu_timer t;
46 for (size_t i = 0; i < count; ++i)
47 {
48 Generator gen;
49 boost::uuids::uuid u = gen();
50 boost::ignore_unused(u);
51 }
52}
53
54template<class Generator>
55void auto_timed_generator_reuse(size_t count)
56{
57 Generator gen;
58 {
59 boost::timer::auto_cpu_timer t;
60 for (size_t i = 0; i < count; ++i)
61 {
62 boost::uuids::uuid u = gen();
63 boost::ignore_unused(u);
64 }
65 }
66}
67
68template<class Generator>
69boost::timer::cpu_times timed_generator(size_t count)
70{
71 boost::timer::cpu_timer t;
72 Generator gen;
73 for (size_t i = 0; i < count; ++i)
74 {
75 boost::uuids::uuid u = gen();
76 boost::ignore_unused(u);
77 }
78 return t.elapsed();
79}
80
81int main(int, char*[])
82{
83 std::cout << "Operating system entropy provider: "
84 << boost::uuids::detail::random_provider().name() << std::endl;
85
92f5a8d4 86#if !defined(BOOST_NO_STRESS_TEST)
11fdf7f2
TL
87
88 //
89 // Determine the cutoff point where it is more wall-clock efficient to
90 // use the bulk generator over the standard one.
91 //
92
93 std::cout << "Calculating the number of operator() calls where random_generator" << std::endl;
94 std::cout << "is more efficient than random_generator_mt19937..." << std::endl;
95 std::cout << "at ";
96 bool asterisk = false;
97 size_t minn = (std::numeric_limits<size_t>::max)();
98 size_t summ = 0;
99 size_t maxx = 0;
100 for (size_t i = 0; i < AVG_LOOPS + 1; ++i) // the first loop is thrown away, see below
101 {
102 size_t answer = 0;
103 for (size_t count = 1; !answer; ++count)
104 {
105 boost::timer::cpu_times standard = timed_generator<boost::uuids::random_generator>(count);
106 boost::timer::cpu_times pseudo = timed_generator<boost::uuids::random_generator_mt19937>(count);
107 if (standard.wall > pseudo.wall)
108 {
109 answer = count;
110 }
111 else if (count >= 999)
112 {
113 std::cout << "*";
114 asterisk = true;
115 answer = count;
116 }
117 }
118
119 // throw away the first answer in case it contains time related to loading
120 // or initializing the crypto library being used
121 if (i > 0)
122 {
123 if (minn > answer) minn = answer;
124 if (maxx < answer) maxx = answer;
125 summ += answer;
126 std::cout << answer << " " << std::flush;
127 }
128 }
129 if (asterisk)
130 {
131 std::cout << "* = limited to 999" << std::endl;
132 }
133 std::cout << "calls to operator()" << std::endl;
134 size_t answer = summ / AVG_LOOPS;
135 std::cout << "For this platform, random_generator_mt19937 outperforms "
136 << "random_generator after " << answer << " generations (min " << minn << " / max " << maxx << ")."
137 << std::endl;
138 std::cout << std::endl;
139
140#endif
141
142 //
143 // Measure ctor/dtor of both
144 //
145 std::cout << "Construction/destruction time for random_generator "
146 << "(" << GEN_LOOPS << " iterations): " << std::endl;
147 auto_timed_generator_ctordtor<boost::uuids::random_generator>(GEN_LOOPS);
148 std::cout << std::endl;
149
150 std::cout << "Construction/destruction time for random_generator_mt19937 "
151 << "(" << GEN_LOOPS << " iterations): " << std::endl;
152 auto_timed_generator_ctordtor<boost::uuids::random_generator_mt19937>(GEN_LOOPS);
153 std::cout << std::endl;
154
155 //
156 // Two common use cases:
157 //
158 // Use an OS provided RNG which has no seed code but is slower to reuse
159 // Use a PRNG which is expensive to seed once but fast to reuse
160 //
161 // Measure the default selections of the library
162 //
163
164 std::cout << "Benchmark boost::uuids::random_generator "
165 << "(reused for " << REUSE_LOOPS << " loops):" << std::endl;
166 auto_timed_generator_reuse<boost::uuids::random_generator>(REUSE_LOOPS);
167 std::cout << std::endl;
168
169 std::cout << "Benchmark boost::uuids::random_generator_mt19937 "
170 << "(reused for " << REUSE_LOOPS << " loops):" << std::endl;
171 auto_timed_generator_reuse<boost::uuids::random_generator_mt19937>(REUSE_LOOPS);
172 std::cout << std::endl;
173
174 std::cout << "Benchmark boost::uuids::random_generator "
175 << "(new generator each loop for " << GEN_LOOPS << " loops):" << std::endl;
176 auto_timed_generator_novel<boost::uuids::random_generator>(GEN_LOOPS);
177 std::cout << std::endl;
178
179 std::cout << "Benchmark boost::uuids::random_generator_mt19937 "
180 << "(new generator each loop for " << GEN_LOOPS << " loops):" << std::endl;
181 auto_timed_generator_novel<boost::uuids::random_generator_mt19937>(GEN_LOOPS);
182 std::cout << std::endl;
183
184 return 0;
185}
186
187