1 // boost run_timer_test.cpp -----------------------------------------------------//
3 // Copyright Beman Dawes 2006, 2008
4 // Copyright 2009 Vicente J. Botet Escriba
6 // Distributed under the Boost Software License, Version 1.0.
7 // See http://www.boost.org/LICENSE_1_0.txt
9 // See http://www.boost.org/libs/chrono for documentation.
11 #include <boost/chrono/process_times.hpp>
12 #include <boost/chrono/timer.hpp>
13 #include <cstdlib> // for atol()
18 #include <cmath> // for sqrt(), used to burn time
20 using boost::chrono::run_timer
;
21 using boost::system::error_code
;
23 #include <boost/detail/lightweight_test.hpp>
25 //#define BOOST_TEST(expr) if (!(expr)) std::cout << "*****ERROR*****\n"
27 #define CHECK_REPORT(Timer,String_Stream,R,U,S,Expected_String) \
28 check_report(Timer, String_Stream, R, U, S, Expected_String, __LINE__)
33 typedef boost::chrono::nanoseconds ns
;
35 bool check_report( run_timer
& tmr
, std::stringstream
& ss
,
36 run_timer::duration r
, run_timer::duration u
, run_timer::duration s
,
37 const std::string
& expected
, int line
)
39 tmr
.test_report(r
,u
,s
);
41 if ( ss
.str() != expected
)
43 std::cout
<< "run_timer_test.cpp(" << line
<< ") : error: actual output \""
44 << ss
.str() << "\" != expected \"" << expected
<< "\"\n";
50 void run_timer_constructor_overload_test()
52 // exercise each supported combination of constructor arguments
54 std::ostream
& os
= std::cout
;
56 boost::system::error_code ec
;
61 run_timer
t4( os
, ec
);
63 run_timer
t6( os
, pl
);
64 run_timer
t7( pl
, ec
);
65 run_timer
t8( os
, pl
, ec
);
66 run_timer
t9( "t9, default places, r %r, c %c, p %p, u %u, s %s\n" );
67 run_timer
t10( os
, "t10, default places, r %r, c %c, p %p, u %u, s %s\n" );
68 run_timer
t11( "t11, default places, r %r, c %c, p %p, u %u, s %s\n", ec
);
69 run_timer
t12( os
, "t12, default places, r %r, c %c, p %p, u %u, s %s\n", ec
);
70 run_timer
t13( pl
, "t13, explicitly code places, r %r, c %c, p %p, u %u, s %s\n" );
71 run_timer
t14( "t14, explicitly code places, r %r, c %c, p %p, u %u, s %s\n", pl
);
72 run_timer
t15( os
, pl
, "t15, explicitly code places, r %r, c %c, p %p, u %u, s %s\n" );
73 run_timer
t16( os
, "t16, explicitly code places, r %r, c %c, p %p, u %u, s %s\n", pl
);
74 run_timer
t17( pl
, "t17, explicitly code places, r %r, c %c, p %p, u %u, s %s\n", ec
);
75 run_timer
t18( "t18, explicitly code places, r %r, c %c, p %p, u %u, s %s\n", pl
, ec
);
76 run_timer
t19( os
, pl
, "t19, explicitly code places, r %r, c %c, p %p, u %u, s %s\n", ec
);
77 run_timer
t20( os
, "t20, explicitly code places, r %r, c %c, p %p, u %u, s %s\n", pl
, ec
);
79 std::cout
<< "Burn some time so run_timers have something to report...";
80 boost::chrono::timer
<boost::chrono::high_resolution_clock
> t
;
81 while ( t
.elapsed() < boost::chrono::seconds(1) ) {}
83 std::cout
<< run_timer::default_places() << " default places\n";
84 std::cout
<< pl
<< " explicitly coded places\n";
88 void accuracy_test( int argc
, char * argv
[] )
90 long timeout_in_secs
= 1;
91 if ( argc
> 1 ) timeout_in_secs
= std::atol( argv
[1] );
92 std::cout
<< "accuracy test for " << timeout_in_secs
<< " second(s)...";
94 std::clock_t timeout_in_clock_t
= std::clock();
95 timeout_in_clock_t
+= (timeout_in_secs
* CLOCKS_PER_SEC
);
97 boost::chrono::system_timer sys
;
98 #ifdef BOOST_CHRONO_HAS_CLOCK_STEADY
99 boost::chrono::steady_timer mono
;
101 boost::chrono::high_resolution_timer hires
;
102 boost::chrono::process_timer process
;
108 } while ( now
< timeout_in_clock_t
);
110 boost::chrono::system_timer::duration sys_dur
= sys
.elapsed();
111 #ifdef BOOST_CHRONO_HAS_CLOCK_STEADY
112 boost::chrono::steady_timer::duration mono_dur
= mono
.elapsed();
114 boost::chrono::high_resolution_timer::duration hires_dur
= hires
.elapsed();
115 boost::chrono::process_times times
;
116 process
.elapsed( times
);
118 std::cout
<< std::endl
;
120 ns
timeout_in_nanoseconds( static_cast<long long>(timeout_in_secs
) * 1000000000LL );
122 // Allow 20% leeway. Particularly on Linux, there seems to be a large discrepancy
123 // between std::clock() and higher resolution clocks.
124 ns
maximum_delta ( static_cast<long long>(timeout_in_nanoseconds
.count() * 0.20 ) );
126 std::cout
<< timeout_in_nanoseconds
.count() << " timeout_in_nanoseconds\n";
127 std::cout
<< maximum_delta
.count() << " maximum_delta\n";
129 std::cout
<< sys_dur
.count() << " sys_dur\n";
131 BOOST_TEST( sys_dur
> timeout_in_nanoseconds
- maximum_delta
132 && sys_dur
< timeout_in_nanoseconds
+ maximum_delta
);
134 #ifdef BOOST_CHRONO_HAS_CLOCK_STEADY
135 std::cout
<< mono_dur
.count() << " mono_dur\n";
137 BOOST_TEST( mono_dur
> timeout_in_nanoseconds
- maximum_delta
138 && mono_dur
< timeout_in_nanoseconds
+ maximum_delta
);
141 std::cout
<< hires_dur
.count() << " hires_dur\n";
143 BOOST_TEST( hires_dur
> timeout_in_nanoseconds
- maximum_delta
144 && hires_dur
< timeout_in_nanoseconds
+ maximum_delta
);
146 std::cout
<< times
.real
.count() << " times.real\n";
148 BOOST_TEST( times
.real
> timeout_in_nanoseconds
- maximum_delta
149 && times
.real
< timeout_in_nanoseconds
+ maximum_delta
);
157 std::stringstream ss
;
159 BOOST_TEST( CHECK_REPORT(t
, ss
, ns(0), ns(0), ns(0),
160 "\nreal 0.000s, cpu 0.000s (0.0%), user 0.000s, system 0.000s\n" ) );
164 std::stringstream ss
;
166 BOOST_TEST( CHECK_REPORT(t
, ss
, ns(3000000000LL), ns(2000000000LL), ns(1000000000LL),
167 "\nreal 3.000s, cpu 3.000s (100.0%), user 2.000s, system 1.000s\n" ) );
171 std::stringstream ss
;
172 run_timer
t( ss
, "9 places: r %r, c %c, p %p, u %u, s %s", 9 );
173 BOOST_TEST( CHECK_REPORT(t
, ss
, ns(3000000003LL), ns(2000000002LL), ns(1000000001LL),
175 "r 3.000000003, c 3.000000003, p 100.0, u 2.000000002, s 1.000000001" ) );
179 // process_timer_test
181 void process_timer_test()
183 std::cout
<< "process_timer_test..." << std::flush
;
185 boost::chrono::process_timer t
;
186 double res
=0; // avoids optimization
187 for (long i
= 0; i
< 10000000L; ++i
)
189 res
+=std::sqrt( static_cast<double>(i
) ); // avoids optimization
192 boost::chrono::process_times times
;
193 times
.real
= times
.system
= times
.user
= ns(0);
195 BOOST_TEST( times
.real
== ns(0) );
196 BOOST_TEST( times
.user
== ns(0) );
197 BOOST_TEST( times
.system
== ns(0) );
202 std::cout
<< times
.real
.count() << " times.real\n";
203 std::cout
<< times
.user
.count() << " times.user\n";
204 std::cout
<< times
.system
.count() << " times.system\n";
205 std::cout
<< (times
.user
+times
.system
).count() << " times.user+system\n";
206 BOOST_TEST( times
.real
> ns(1) );
208 BOOST_TEST( times
.user
+times
.system
> ns(1) );
210 std::cout
<< "complete " << res
<< std::endl
;
214 int main( int argc
, char * argv
[] )
216 std::locale
loc( "" ); // test with appropriate locale
217 std::cout
.imbue( loc
);
219 accuracy_test( argc
, argv
);
220 run_timer_constructor_overload_test();
221 process_timer_test();
224 return boost::report_errors();