]>
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.
7 #include "./prepare.hpp"
9 #include <boost/convert.hpp>
10 #include <boost/convert/stream.hpp>
11 #include <boost/convert/printf.hpp>
12 #include <boost/convert/strtol.hpp>
13 #include <boost/convert/spirit.hpp>
14 #include <boost/convert/lexical_cast.hpp>
15 #include <boost/detail/lightweight_test.hpp>
16 #include <boost/timer/timer.hpp>
17 #include <boost/array.hpp>
18 #include <boost/random/mersenne_twister.hpp>
19 #include <boost/random/uniform_int_distribution.hpp>
26 namespace cnv
= boost::cnv
;
27 namespace arg
= boost::cnv::parameter
;
29 namespace { namespace local
31 template<typename Type
>
34 typedef boost::array
<Type
, 20> type
;
36 template<typename T
> static typename array
<T
>::type
const& get();
38 static int const num_cycles
= 1000000;
41 struct timer
: public boost::timer::cpu_timer
43 typedef timer this_type
;
44 typedef boost::timer::cpu_timer base_type
;
48 boost::timer::cpu_times times
= base_type::elapsed();
49 int const use_sum
= (sum
% 2) ? 0 : (sum
% 2); BOOST_TEST(use_sum
== 0);
51 return double(times
.user
+ times
.system
) / 1000000000 + use_sum
;
54 template< typename Type
, typename Cnv
> static double str_to (Cnv
const&);
55 template<typename S
, typename Type
, typename Cnv
> static double to_str (Cnv
const&);
58 local::array
<int>::type
const&
61 static array
<int>::type ints
;
66 boost::random::mt19937
gen (::time(0));
67 boost::random::uniform_int_distribution
<> dist (INT_MIN
, INT_MAX
); // INT_MAX(32) = 2,147,483,647
69 for (size_t k
= 0; k
< ints
.size(); ++k
)
77 array
<long int>::type
const&
80 static array
<long int>::type ints
;
85 boost::random::mt19937
gen (::time(0));
86 boost::random::uniform_int_distribution
<> dist (INT_MIN
, INT_MAX
); // INT_MAX(32) = 2147483647
88 for (size_t k
= 0; k
< ints
.size(); ++k
)
96 array
<double>::type
const&
99 static array
<double>::type dbls
;
104 boost::random::mt19937
gen (::time(0));
105 boost::random::uniform_int_distribution
<> dist (INT_MIN
, INT_MAX
); // INT_MAX(32) = 2147483647
107 for (size_t k
= 0; k
< dbls
.size(); ++k
)
108 dbls
[k
] = double(dist(gen
)) + 0.7654321;
116 struct raw_str_to_int_spirit
118 int operator()(char const* str
) const
120 char const* beg
= str
;
121 char const* end
= beg
+ strlen(str
);
124 if (boost::spirit::qi::parse(beg
, end
, boost::spirit::int_
, result
))
125 if (beg
== end
) // ensure the whole string was parsed
128 return (BOOST_ASSERT(0), result
);
132 struct raw_str_to_int_lxcast
134 int operator()(char const* str
) const
136 return boost::lexical_cast
<int>(str
);
140 template<typename Type
, typename Converter
>
142 raw_str_to(Converter
const& cnv
)
144 local::strings strings
= local::get_strs(); // Create strings on the stack
145 int const size
= strings
.size();
148 for (int t
= 0; t
< local::num_cycles
; ++t
)
149 for (int k
= 0; k
< size
; ++k
)
150 local::sum
+= cnv(strings
[k
].c_str());
152 return timer
.value();
155 template<typename Type
, typename Converter
>
157 local::str_to(Converter
const& try_converter
)
159 local::strings strings
= local::get_strs(); // Create strings on the stack
160 int const size
= strings
.size();
163 for (int t
= 0; t
< local::num_cycles
; ++t
)
164 for (int k
= 0; k
< size
; ++k
)
165 local::sum
+= boost::convert
<Type
>(strings
[k
].c_str(), try_converter
).value();
167 return timer
.value();
170 template<typename string_type
, typename Type
, typename Converter
>
172 local::to_str(Converter
const& try_converter
)
174 typedef typename
local::array
<Type
>::type collection
;
176 collection values
= local::get
<Type
>();
177 int const size
= values
.size();
180 for (int t
= 0; t
< local::num_cycles
; ++t
)
181 for (int k
= 0; k
< size
; ++k
)
182 local::sum
+= *boost::convert
<string_type
>(Type(values
[k
]), try_converter
).value().begin();
184 return timer
.value();
187 template<typename Converter
>
189 performance_str_to_type(Converter
const& try_converter
)
191 char const* input
[] = { "no", "up", "dn" };
194 for (int k
= 0; k
< local::num_cycles
; ++k
)
196 change chg
= boost::convert
<change
>(input
[k
% 3], try_converter
).value();
197 int res
= chg
.value();
199 BOOST_TEST(res
== k
% 3);
201 local::sum
+= res
; // Make sure chg is not optimized out
203 return timer
.value();
206 template<typename Converter
>
208 performance_type_to_str(Converter
const& try_converter
)
210 boost::array
<change
, 3> input
= {{ change::no
, change::up
, change::dn
}};
211 boost::array
<string
, 3> results
= {{ "no", "up", "dn" }};
214 for (int k
= 0; k
< local::num_cycles
; ++k
)
216 string res
= boost::convert
<string
>(input
[k
% 3], try_converter
).value();
218 BOOST_TEST(res
== results
[k
% 3]);
220 local::sum
+= res
[0]; // Make sure res is not optimized out
222 return timer
.value();
225 template<typename Raw
, typename Cnv
>
227 performance_comparative(Raw
const& raw
, Cnv
const& cnv
, char const* txt
)
229 int const num_tries
= 5;
233 for (int k
= 0; k
< num_tries
; ++k
) cnv_time
+= local::str_to
<int>(cnv
);
234 for (int k
= 0; k
< num_tries
; ++k
) raw_time
+= raw_str_to
<int>(raw
);
236 cnv_time
/= num_tries
;
237 raw_time
/= num_tries
;
239 double change
= 100 * (1 - cnv_time
/ raw_time
);
241 printf("str-to-int: %s raw/cnv=%.2f/%.2f seconds (%.2f%%).\n", txt
, raw_time
, cnv_time
, change
);
245 main(int, char const* [])
247 printf("Started performance tests...\n");
249 printf("str-to-int: spirit/strtol/lcast/scanf/stream=%7.2f/%7.2f/%7.2f/%7.2f/%7.2f seconds.\n",
250 local::str_to
<int>(boost::cnv::spirit()),
251 local::str_to
<int>(boost::cnv::strtol()),
252 local::str_to
<int>(boost::cnv::lexical_cast()),
253 local::str_to
<int>(boost::cnv::printf()),
254 local::str_to
<int>(boost::cnv::cstream()));
255 printf("str-to-lng: spirit/strtol/lcast/scanf/stream=%7.2f/%7.2f/%7.2f/%7.2f/%7.2f seconds.\n",
256 local::str_to
<long int>(boost::cnv::spirit()),
257 local::str_to
<long int>(boost::cnv::strtol()),
258 local::str_to
<long int>(boost::cnv::lexical_cast()),
259 local::str_to
<long int>(boost::cnv::printf()),
260 local::str_to
<long int>(boost::cnv::cstream()));
261 printf("str-to-dbl: spirit/strtol/lcast/scanf/stream=%7.2f/%7.2f/%7.2f/%7.2f/%7.2f seconds.\n",
262 local::str_to
<double>(boost::cnv::spirit()),
263 local::str_to
<double>(boost::cnv::strtol()),
264 local::str_to
<double>(boost::cnv::lexical_cast()),
265 local::str_to
<double>(boost::cnv::printf()),
266 local::str_to
<double>(boost::cnv::cstream()));
268 printf("int-to-str: spirit/strtol/lcast/prntf/stream=%7.2f/%7.2f/%7.2f/%7.2f/%7.2f seconds.\n",
269 local::to_str
<std::string
, int>(boost::cnv::spirit()),
270 local::to_str
<std::string
, int>(boost::cnv::strtol()),
271 local::to_str
<std::string
, int>(boost::cnv::lexical_cast()),
272 local::to_str
<std::string
, int>(boost::cnv::printf()),
273 local::to_str
<std::string
, int>(boost::cnv::cstream()));
274 printf("lng-to-str: spirit/strtol/lcast/prntf/stream=%7.2f/%7.2f/%7.2f/%7.2f/%7.2f seconds.\n",
275 local::to_str
<std::string
, long int>(boost::cnv::spirit()),
276 local::to_str
<std::string
, long int>(boost::cnv::strtol()),
277 local::to_str
<std::string
, long int>(boost::cnv::lexical_cast()),
278 local::to_str
<std::string
, long int>(boost::cnv::printf()),
279 local::to_str
<std::string
, long int>(boost::cnv::cstream()));
280 printf("dbl-to-str: spirit/strtol/lcast/prntf/stream=%7.2f/%7.2f/%7.2f/%7.2f/%7.2f seconds.\n",
281 local::to_str
<std::string
, double>(boost::cnv::spirit()),
282 local::to_str
<std::string
, double>(boost::cnv::strtol()(arg::precision
= 6)),
283 local::to_str
<std::string
, double>(boost::cnv::lexical_cast()),
284 local::to_str
<std::string
, double>(boost::cnv::printf()(arg::precision
= 6)),
285 local::to_str
<std::string
, double>(boost::cnv::cstream()(arg::precision
= 6)));
287 printf("str-to-user-type: lcast/stream/strtol=%.2f/%.2f/%.2f seconds.\n",
288 performance_str_to_type(boost::cnv::lexical_cast()),
289 performance_str_to_type(boost::cnv::cstream()),
290 performance_str_to_type(boost::cnv::strtol()));
291 printf("user-type-to-str: lcast/stream/strtol=%.2f/%.2f/%.2f seconds.\n",
292 performance_type_to_str(boost::cnv::lexical_cast()),
293 performance_type_to_str(boost::cnv::cstream()),
294 performance_type_to_str(boost::cnv::strtol()));
296 //[small_string_results
297 printf("strtol int-to std::string/small-string: %.2f/%.2f seconds.\n",
298 local::to_str
<std::string
, int>(boost::cnv::strtol()),
299 local::to_str
< my_string
, int>(boost::cnv::strtol()));
300 printf("spirit int-to std::string/small-string: %.2f/%.2f seconds.\n",
301 local::to_str
<std::string
, int>(boost::cnv::spirit()),
302 local::to_str
< my_string
, int>(boost::cnv::spirit()));
303 printf("stream int-to std::string/small-string: %.2f/%.2f seconds.\n",
304 local::to_str
<std::string
, int>(boost::cnv::cstream()),
305 local::to_str
< my_string
, int>(boost::cnv::cstream()));
307 performance_comparative(raw_str_to_int_spirit(), boost::cnv::spirit(), "spirit");
308 performance_comparative(raw_str_to_int_lxcast(), boost::cnv::lexical_cast(), "lxcast");
310 return boost::report_errors();