]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/format/benchmark/bench_format.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / format / benchmark / bench_format.cpp
1 // -*- C++ -*-
2 // Boost general library 'format' ---------------------------
3 // See http://www.boost.org for updates, documentation, and revision history.
4
5 // Copyright (c) 2001 Samuel Krempp
6 // krempp@crans.ens-cachan.fr
7 // Distributed under the Boost Software License, Version 1.0. (See
8 // accompanying file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10
11 // several suggestions from Jens Maurer
12
13 // ------------------------------------------------------------------------------
14 // bench_variants.cc : do the same task, with snprintf, stream, and format
15 // and compare their times.
16
17 // This benchmark is provided purely for information.
18 // It might not even compile as-is,
19 // or not give any sensible results.
20 // (e.g., it expects sprintf to be POSIX compliant)
21
22 // ------------------------------------------------------------------------------
23
24
25 #include <iostream>
26 #include <iomanip>
27 #include <cstdio> // sprintf
28 #include <cstring>
29 #include <fstream>
30 #include <cmath> // floor
31 #include <boost/timer.hpp>
32
33 #include <boost/format.hpp>
34
35 //#define knelson
36
37 #ifdef knelson
38 namespace KNelson {
39 #include "boost/format3.hpp"
40 }
41 #endif
42
43
44
45
46 // portable /dev/null stream equivalent, by James Kanze, http://www.gabi-soft.de
47 class NulStreambuf : public std::streambuf
48 {
49 public:
50 NulStreambuf() {
51 setp( dummyBuffer , dummyBuffer + 64 ) ;
52 }
53 virtual int overflow( int c );
54 virtual int underflow();
55 private:
56 char dummyBuffer[ 64 ] ;
57 } ;
58
59 class NulStream : public std::basic_ostream<char, std::char_traits<char> >
60 {
61 public:
62 NulStream();
63 virtual ~NulStream();
64 NulStreambuf* rdbuf() {
65 return static_cast< NulStreambuf* >(
66 ((std::basic_ostream<char, std::char_traits<char> > *) this) -> rdbuf() ) ;
67 }
68 } ;
69
70
71 //-------------------------------------------------------------------------------------
72 // NulStream implementation
73
74 NulStream::NulStream() : std::basic_ostream<char, std::char_traits<char> > (NULL) {
75 init( new NulStreambuf ) ;
76 }
77
78 NulStream::~NulStream() {
79 delete rdbuf() ;
80 }
81
82 int NulStreambuf::underflow(){ return std::ios::traits_type::eof();
83 }
84
85 int NulStreambuf::overflow( int c ){
86 setp( dummyBuffer , dummyBuffer + 64 ) ;
87 return (c == std::ios::traits_type::eof()) ? '\0' : c ;
88 }
89
90
91
92 // -------------------------------------------------------------------------------------
93
94 static int NTests = 300000;
95
96 //static std::stringstream nullStream;
97 static NulStream nullStream;
98 static double tstream, tpf;
99 //static const std::string fstring="%3$#x %1$20.10E %2$g %3$d \n";
100 static const std::string fstring="%3$0#6x %1$20.10E %2$g %3$0+5d \n";
101 static const double arg1=45.23;
102 static const double arg2=12.34;
103 static const int arg3=23;
104 static const std::string res =
105 "0x0017 4.5230000000E+01 12.34 +0023 \n";
106 //static const std::string res = "23.0000 4.5230000000E+01 12.34 23 \n";
107 void test_snprintf();
108 void test_nullstream();
109 void test_opti_nullstream();
110 void test_parsed_once_format();
111 void test_reused_format();
112 void test_format();
113 void test_try1();
114 void test_try2();
115
116 #ifdef knelson
117 void test_format3();
118 #endif
119
120 int main(int argc, char * argv[]) {
121 using namespace boost;
122 using namespace std;
123 const string::size_type npos = string::npos;
124
125 string choices="";
126 if(1<argc) {
127 choices = (argv[1]); // profiling is easier launching only one.
128 NTests = 1000*1000; // andmoreprecise with many iterations
129 cout << "choices (" << choices << ") \n";
130 }
131
132 if(choices=="" || choices.find('p') !=npos)
133 test_snprintf();
134 if(choices=="" || choices.find('n') !=npos)
135 test_nullstream();
136 if(choices=="" || choices.find('1') !=npos)
137 test_parsed_once_format();
138 if(choices=="" || choices.find('r') !=npos)
139 test_reused_format();
140 if(choices=="" || choices.find('f') !=npos)
141 test_format();
142 if(choices.find('t') !=npos)
143 test_try1();
144 if(choices.find('y') !=npos)
145 test_try2();
146 if(choices.find('o') !=npos)
147 test_opti_nullstream();
148 #ifdef knelson
149 if(choices=="" || choices.find('k') !=npos)
150 test_format3();
151 #endif
152 return 0;
153 }
154
155
156 void test_snprintf()
157 {
158 using namespace std;
159
160 // Check that snpintf is Unix98 compatible on the platform :
161 char * buf = new char[4000];
162 sprintf(buf, fstring.c_str(), arg1, arg2, arg3);
163 if( strncmp( buf, res.c_str(), res.size()) != 0 ) {
164 cerr << endl << buf;
165 }
166 // time the loop :
167 boost::timer chrono;
168 for(int i=0; i<NTests; ++i) {
169 sprintf(buf, fstring.c_str(), arg1, arg2, arg3);
170 }
171 tpf=chrono.elapsed();
172 cout << left << setw(20) <<"printf time"<< right <<":" << tpf << endl;
173 }
174
175 void test_try1()
176 {
177 using namespace std;
178 boost::io::basic_oaltstringstream<char> oss;
179 oss << boost::format(fstring) % arg1 % arg2 % arg3;
180 boost::timer chrono;
181 int dummy=0;
182 for(int i=0; i<NTests; ++i) {
183 dummy += oss.cur_size();
184 }
185 double t = chrono.elapsed();
186 cout << left << setw(20) <<"try1 time"<< right <<":" << setw(5) << t
187 << ", = " << t / tpf << " * printf "
188 << ", = " << t / tstream << " * nullStream \n";
189 }
190
191 void test_try2()
192 {
193 using namespace std;
194 boost::io::basic_oaltstringstream<char> oss;
195 oss << boost::format(fstring) % arg1 % arg2 % arg3;
196 oss << "blas 34567890GGGGGGGGGGGGGGGGGGGGGGGGGGGGggggggggggggggggggggggggggg " << endl;
197 string s = oss.cur_str();
198 oss << s << s << s;
199 oss.clear_buffer();
200 oss << s << s;
201 s = oss.cur_str();
202 boost::timer chrono;
203 int dummy=0;
204 for(int i=0; i<NTests; ++i) {
205 dummy += oss.cur_size();
206 }
207 double t = chrono.elapsed();
208 cout << left << setw(20) <<"try2 time"<< right <<":" << setw(5) << t
209 << ", = " << t / tpf << " * printf "
210 << ", = " << t / tstream << " * nullStream \n";
211 }
212
213 void do_stream(std::ostream& os) {
214 using namespace std;
215 std::ios_base::fmtflags f = os.flags();
216 os << hex << showbase << internal << setfill('0') << setw(6) << arg3
217 << dec << noshowbase << right << setfill(' ')
218 << " "
219 << scientific << setw(20) << setprecision(10) << uppercase << arg1
220 << setprecision(6) << nouppercase ;
221 os.flags(f);
222 os << " " << arg2 << " "
223 << showpos << setw(5) << internal << setfill('0') << arg3 << " \n" ;
224 os.flags(f);
225 }
226
227 void test_nullstream()
228 {
229 using namespace std;
230 boost::timer chrono;
231 boost::io::basic_oaltstringstream<char> oss;
232
233 {
234 do_stream(oss);
235 if(oss.str() != res ) {
236 cerr << endl << oss.str() ;
237 }
238 }
239
240 for(int i=0; i<NTests; ++i) {
241 do_stream(nullStream);
242 }
243
244 // for(int i=0; i<NTests; ++i) {
245 // std::ios_base::fmtflags f0 = nullStream.flags();
246 // nullStream << hex << showbase << arg3
247 // << dec << noshowbase << " "
248 // << scientific << setw(20) << setprecision(10) << uppercase << arg1
249 // << setprecision(0);
250 // nullStream.flags(f0);
251 // nullStream << " " << arg2 << " " << arg3 << " \n" ;
252
253 // }
254 double t = chrono.elapsed();
255 cout << left << setw(20) <<"ostream time"<< right <<":" << setw(5) << t
256 << ", = " << t / tpf << " * printf \n";
257 tstream = t;
258 }
259
260 void test_opti_nullstream()
261 {
262 using namespace std;
263 boost::timer chrono;
264 boost::io::basic_oaltstringstream<char> oss;
265 //static const std::string fstring="%3$#x %1$20.10E %2$g %3$d \n";
266
267 std::ios_base::fmtflags f0 = oss.flags(), f1, f2;
268 streamsize p0 = oss.precision();
269 {
270 oss << hex << showbase;
271 f1 = oss.flags();
272 oss << arg3;
273
274 oss.flags(f0);
275 oss << " " << scientific << setw(20) << setprecision(10) << uppercase;
276 f2 = oss.flags();
277 oss << arg1;
278
279 oss.flags(f0); oss.precision(p0);
280 oss << " " << arg2 << " " << arg3 << " \n" ;
281
282 if(oss.str() != res ) {
283 cerr << endl << oss.str() ;
284 }
285 }
286
287 for(int i=0; i<NTests; ++i) {
288 nullStream.flags(f1);
289 nullStream << arg3;
290
291 nullStream << setw(20) << setprecision(10);
292 nullStream.flags(f2);
293 nullStream << arg1;
294
295 nullStream.flags(f0); nullStream.precision(p0);
296 nullStream << " " << arg2 << " " << arg3 << " \n" ;
297 }
298 double t = chrono.elapsed();
299 cout << left << setw(20) <<"opti-stream time"<< right <<":" << setw(5) << t
300 << ", = " << t / tpf << " * printf \n";
301 // tstream = t;
302 }
303
304 void test_parsed_once_format()
305 {
306 using namespace std;
307 static const boost::format fmter(fstring);
308
309 boost::io::basic_oaltstringstream<char> oss;
310 oss << boost::format(fmter) % arg1 % arg2 % arg3 ;
311 if( oss.str() != res ) {
312 cerr << endl << oss.str();
313 }
314
315 // not only is the format-string parsed once,
316 // but also the buffer of the internal stringstream is already allocated.
317
318 boost::timer chrono;
319 for(int i=0; i<NTests; ++i) {
320 nullStream << boost::format(fmter) % arg1 % arg2 % arg3;
321 }
322 double t=chrono.elapsed();
323 cout << left << setw(20) <<"parsed-once time"<< right <<":" << setw(5) << t
324 << ", = " << t / tpf << " * printf "
325 << ", = " << t / tstream << " * nullStream \n";
326 }
327
328 void test_reused_format()
329 {
330 using namespace std;
331 boost::io::basic_oaltstringstream<char> oss;
332 oss << boost::format(fstring) % arg1 % arg2 % arg3;
333 if(oss.str() != res ) {
334 cerr << endl << oss.str();
335 }
336
337 boost::timer chrono;
338 boost::format fmter;
339 for(int i=0; i<NTests; ++i) {
340 nullStream << fmter.parse(fstring) % arg1 % arg2 % arg3;
341 }
342 double t = chrono.elapsed();
343 cout << left << setw(20) <<"reused format time"<< right <<":" << setw(5) << t
344 << ", = " << t / tpf << " * printf "
345 << ", = " << t / tstream << " * nullStream \n";
346 }
347
348 void test_format()
349 {
350 using namespace std;
351 boost::io::basic_oaltstringstream<char> oss;
352 oss << boost::format(fstring) % arg1 % arg2 % arg3;
353 if(oss.str() != res ) {
354 cerr << endl << oss.str();
355 }
356
357 boost::timer chrono;
358 for(int i=0; i<NTests; ++i) {
359 nullStream << boost::format(fstring) % arg1 % arg2 % arg3;
360 }
361 double t = chrono.elapsed();
362 cout << left << setw(20) <<"format time"<< right <<":" << setw(5) << t
363 << ", = " << t / tpf << " * printf "
364 << ", = " << t / tstream << " * nullStream \n";
365 }
366
367
368 #ifdef knelson
369 void test_format3()
370 {
371 using namespace std;
372 boost::io::basic_oaltstringstream<char> oss;
373 oss << KNelson::boost::format(fstring.c_str(), arg1, arg2, arg3);
374 if(oss.str() != res ) {
375 cerr << endl << oss.str();
376 }
377
378 boost::timer chrono;
379 for(int i=0; i<NTests; ++i) {
380 nullStream << KNelson::boost::format(fstring.c_str(), arg1, arg2, arg3);
381 }
382 double t = chrono.elapsed();
383 cout << left << setw(20) <<"format3 time"<< right <<":" << setw(5) << t
384 << ", = " << t / tpf << " * printf "
385 << ", = " << t / tstream << " * nullStream \n" ;
386 }
387
388 #endif