]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/convert/test/performance.cpp
1 // Boost.Convert test and usage example
2 // Copyright (c) 2009-2016 Vladimir Batov.
3 // Use, modification and distribution are subject to the Boost Software License,
4 // Version 1.0. See http://www.boost.org/LICENSE_1_0.txt.
8 #if defined(BOOST_CONVERT_IS_NOT_SUPPORTED)
9 int main(int, char const* []) { return 0; }
12 #include "./prepare.hpp"
13 #include <boost/convert.hpp>
14 #include <boost/convert/stream.hpp>
15 #include <boost/convert/printf.hpp>
16 #include <boost/convert/strtol.hpp>
17 #include <boost/convert/spirit.hpp>
18 #include <boost/convert/lexical_cast.hpp>
19 #include <boost/detail/lightweight_test.hpp>
20 #include <boost/timer/timer.hpp>
21 #include <boost/array.hpp>
22 #include <boost/random/mersenne_twister.hpp>
23 #include <boost/random/uniform_int_distribution.hpp>
30 namespace cnv
= boost::cnv
;
31 namespace arg
= boost::cnv::parameter
;
33 namespace { namespace local
35 template<typename Type
>
38 typedef boost::array
<Type
, 20> type
;
40 template<typename T
> static typename array
<T
>::type
const& get();
42 static int const num_cycles
= 1000000;
45 struct timer
: public boost::timer::cpu_timer
47 typedef timer this_type
;
48 typedef boost::timer::cpu_timer base_type
;
52 boost::timer::cpu_times times
= base_type::elapsed();
53 int const use_sum
= (sum
% 2) ? 0 : (sum
% 2); BOOST_TEST(use_sum
== 0);
55 return double(times
.user
+ times
.system
) / 1000000000 + use_sum
;
58 template< typename Type
, typename Cnv
> static double str_to (Cnv
const&);
59 template<typename S
, typename Type
, typename Cnv
> static double to_str (Cnv
const&);
62 local::array
<int>::type
const&
65 static array
<int>::type ints
;
70 boost::random::mt19937
gen (::time(0));
71 boost::random::uniform_int_distribution
<> dist (INT_MIN
, INT_MAX
); // INT_MAX(32) = 2,147,483,647
73 for (size_t k
= 0; k
< ints
.size(); ++k
)
81 array
<long int>::type
const&
84 static array
<long int>::type ints
;
89 boost::random::mt19937
gen (::time(0));
90 boost::random::uniform_int_distribution
<> dist (INT_MIN
, INT_MAX
); // INT_MAX(32) = 2147483647
92 for (size_t k
= 0; k
< ints
.size(); ++k
)
100 array
<double>::type
const&
103 static array
<double>::type dbls
;
108 boost::random::mt19937
gen (::time(0));
109 boost::random::uniform_int_distribution
<> dist (INT_MIN
, INT_MAX
); // INT_MAX(32) = 2147483647
111 for (size_t k
= 0; k
< dbls
.size(); ++k
)
112 dbls
[k
] = double(dist(gen
)) + 0.7654321;
120 struct raw_str_to_int_spirit
122 int operator()(char const* str
) const
124 char const* beg
= str
;
125 char const* end
= beg
+ strlen(str
);
128 if (boost::spirit::qi::parse(beg
, end
, boost::spirit::int_
, result
))
129 if (beg
== end
) // ensure the whole string was parsed
132 return (BOOST_ASSERT(0), result
);
136 struct raw_str_to_int_lxcast
138 int operator()(char const* str
) const
140 return boost::lexical_cast
<int>(str
);
144 template<typename Type
, typename Converter
>
146 raw_str_to(Converter
const& cnv
)
148 local::strings strings
= local::get_strs(); // Create strings on the stack
149 int const size
= strings
.size();
152 for (int t
= 0; t
< local::num_cycles
; ++t
)
153 for (int k
= 0; k
< size
; ++k
)
154 local::sum
+= cnv(strings
[k
].c_str());
156 return timer
.value();
159 template<typename Type
, typename Converter
>
161 local::str_to(Converter
const& try_converter
)
163 local::strings strings
= local::get_strs(); // Create strings on the stack
164 int const size
= strings
.size();
167 for (int t
= 0; t
< local::num_cycles
; ++t
)
168 for (int k
= 0; k
< size
; ++k
)
169 local::sum
+= boost::convert
<Type
>(strings
[k
].c_str(), try_converter
).value();
171 return timer
.value();
174 template<typename string_type
, typename Type
, typename Converter
>
176 local::to_str(Converter
const& try_converter
)
178 typedef typename
local::array
<Type
>::type collection
;
180 collection values
= local::get
<Type
>();
181 int const size
= values
.size();
184 for (int t
= 0; t
< local::num_cycles
; ++t
)
185 for (int k
= 0; k
< size
; ++k
)
186 local::sum
+= *boost::convert
<string_type
>(Type(values
[k
]), try_converter
).value().begin();
188 return timer
.value();
191 template<typename Converter
>
193 performance_str_to_type(Converter
const& try_converter
)
195 char const* input
[] = { "no", "up", "dn" };
198 for (int k
= 0; k
< local::num_cycles
; ++k
)
200 change chg
= boost::convert
<change
>(input
[k
% 3], try_converter
).value();
201 int res
= chg
.value();
203 BOOST_TEST(res
== k
% 3);
205 local::sum
+= res
; // Make sure chg is not optimized out
207 return timer
.value();
210 template<typename Converter
>
212 performance_type_to_str(Converter
const& try_converter
)
214 boost::array
<change
, 3> input
= {{ change::no
, change::up
, change::dn
}};
215 boost::array
<string
, 3> results
= {{ "no", "up", "dn" }};
218 for (int k
= 0; k
< local::num_cycles
; ++k
)
220 string res
= boost::convert
<string
>(input
[k
% 3], try_converter
).value();
222 BOOST_TEST(res
== results
[k
% 3]);
224 local::sum
+= res
[0]; // Make sure res is not optimized out
226 return timer
.value();
229 template<typename Raw
, typename Cnv
>
231 performance_comparative(Raw
const& raw
, Cnv
const& cnv
, char const* txt
)
233 int const num_tries
= 5;
237 for (int k
= 0; k
< num_tries
; ++k
) cnv_time
+= local::str_to
<int>(cnv
);
238 for (int k
= 0; k
< num_tries
; ++k
) raw_time
+= raw_str_to
<int>(raw
);
240 cnv_time
/= num_tries
;
241 raw_time
/= num_tries
;
243 double change
= 100 * (1 - cnv_time
/ raw_time
);
245 printf("str-to-int: %s raw/cnv=%.2f/%.2f seconds (%.2f%%).\n", txt
, raw_time
, cnv_time
, change
);
249 main(int, char const* [])
251 printf("Started performance tests...\n");
253 printf("str-to-int: spirit/strtol/lcast/scanf/stream=%7.2f/%7.2f/%7.2f/%7.2f/%7.2f seconds.\n",
254 local::str_to
<int>(boost::cnv::spirit()),
255 local::str_to
<int>(boost::cnv::strtol()),
256 local::str_to
<int>(boost::cnv::lexical_cast()),
257 local::str_to
<int>(boost::cnv::printf()),
258 local::str_to
<int>(boost::cnv::cstream()));
259 printf("str-to-lng: spirit/strtol/lcast/scanf/stream=%7.2f/%7.2f/%7.2f/%7.2f/%7.2f seconds.\n",
260 local::str_to
<long int>(boost::cnv::spirit()),
261 local::str_to
<long int>(boost::cnv::strtol()),
262 local::str_to
<long int>(boost::cnv::lexical_cast()),
263 local::str_to
<long int>(boost::cnv::printf()),
264 local::str_to
<long int>(boost::cnv::cstream()));
265 printf("str-to-dbl: spirit/strtol/lcast/scanf/stream=%7.2f/%7.2f/%7.2f/%7.2f/%7.2f seconds.\n",
266 local::str_to
<double>(boost::cnv::spirit()),
267 local::str_to
<double>(boost::cnv::strtol()),
268 local::str_to
<double>(boost::cnv::lexical_cast()),
269 local::str_to
<double>(boost::cnv::printf()),
270 local::str_to
<double>(boost::cnv::cstream()));
272 printf("int-to-str: spirit/strtol/lcast/prntf/stream=%7.2f/%7.2f/%7.2f/%7.2f/%7.2f seconds.\n",
273 local::to_str
<std::string
, int>(boost::cnv::spirit()),
274 local::to_str
<std::string
, int>(boost::cnv::strtol()),
275 local::to_str
<std::string
, int>(boost::cnv::lexical_cast()),
276 local::to_str
<std::string
, int>(boost::cnv::printf()),
277 local::to_str
<std::string
, int>(boost::cnv::cstream()));
278 printf("lng-to-str: spirit/strtol/lcast/prntf/stream=%7.2f/%7.2f/%7.2f/%7.2f/%7.2f seconds.\n",
279 local::to_str
<std::string
, long int>(boost::cnv::spirit()),
280 local::to_str
<std::string
, long int>(boost::cnv::strtol()),
281 local::to_str
<std::string
, long int>(boost::cnv::lexical_cast()),
282 local::to_str
<std::string
, long int>(boost::cnv::printf()),
283 local::to_str
<std::string
, long int>(boost::cnv::cstream()));
284 printf("dbl-to-str: spirit/strtol/lcast/prntf/stream=%7.2f/%7.2f/%7.2f/%7.2f/%7.2f seconds.\n",
285 local::to_str
<std::string
, double>(boost::cnv::spirit()),
286 local::to_str
<std::string
, double>(boost::cnv::strtol()(arg::precision
= 6)),
287 local::to_str
<std::string
, double>(boost::cnv::lexical_cast()),
288 local::to_str
<std::string
, double>(boost::cnv::printf()(arg::precision
= 6)),
289 local::to_str
<std::string
, double>(boost::cnv::cstream()(arg::precision
= 6)));
291 printf("str-to-user-type: lcast/stream/strtol=%.2f/%.2f/%.2f seconds.\n",
292 performance_str_to_type(boost::cnv::lexical_cast()),
293 performance_str_to_type(boost::cnv::cstream()),
294 performance_str_to_type(boost::cnv::strtol()));
295 printf("user-type-to-str: lcast/stream/strtol=%.2f/%.2f/%.2f seconds.\n",
296 performance_type_to_str(boost::cnv::lexical_cast()),
297 performance_type_to_str(boost::cnv::cstream()),
298 performance_type_to_str(boost::cnv::strtol()));
300 //[small_string_results
301 printf("strtol int-to std::string/small-string: %.2f/%.2f seconds.\n",
302 local::to_str
<std::string
, int>(boost::cnv::strtol()),
303 local::to_str
< my_string
, int>(boost::cnv::strtol()));
304 printf("spirit int-to std::string/small-string: %.2f/%.2f seconds.\n",
305 local::to_str
<std::string
, int>(boost::cnv::spirit()),
306 local::to_str
< my_string
, int>(boost::cnv::spirit()));
307 printf("stream int-to std::string/small-string: %.2f/%.2f seconds.\n",
308 local::to_str
<std::string
, int>(boost::cnv::cstream()),
309 local::to_str
< my_string
, int>(boost::cnv::cstream()));
311 performance_comparative(raw_str_to_int_spirit(), boost::cnv::spirit(), "spirit");
312 performance_comparative(raw_str_to_int_lxcast(), boost::cnv::lexical_cast(), "lxcast");
314 return boost::report_errors();