1 /*=============================================================================
2 Copyright (c) 2001-2011 Joel de Guzman
3
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 ==============================================================================*/
7 #include "measure.hpp"
8
9 //~ #define FUSION_MAX_VECTOR_SIZE 30
10
11 #include <boost/fusion/algorithm/iteration/accumulate.hpp>
12 #include <boost/fusion/algorithm/transformation/zip.hpp>
13 #include <boost/fusion/container/vector.hpp>
14 #include <boost/fusion/sequence/intrinsic/value_at.hpp>
15 #include <boost/fusion/sequence/intrinsic/at.hpp>
16 #include <boost/type_traits/remove_reference.hpp>
17 #include <iostream>
18
19 #ifdef _MSC_VER
20 // inline aggressively
21 # pragma inline_recursion(on) // turn on inline recursion
22 # pragma inline_depth(255) // max inline depth
23 #endif
24
25 namespace
26 {
27 struct zip_add
28 {
29 template<typename Lhs, typename Rhs>
30 struct result
31 {
32 typedef typename
33 boost::remove_reference<
34 typename boost::fusion::result_of::value_at_c<Lhs, 0>::type
35 >::type
36 type;
37 };
38
39 template<typename Lhs, typename Rhs>
40 typename result<Lhs, Rhs>::type
operator ()__anon8750fa690111::zip_add41 operator()(const Lhs& lhs, const Rhs& rhs) const
42 {
43 return boost::fusion::at_c<0>(lhs) + boost::fusion::at_c<1>(lhs) + rhs;
44 }
45 };
46
47 // Our Accumulator function
48 template <typename T>
49 struct zip_accumulator
50 {
zip_accumulator__anon8750fa690111::zip_accumulator51 zip_accumulator()
52 : sum()
53 {}
54
55 template <typename Sequence>
operator ()__anon8750fa690111::zip_accumulator56 void operator()(Sequence const& seq)
57 {
58 this->sum += boost::fusion::accumulate(seq, 0, zip_add());
59 }
60
61 T sum;
62 };
63
64 template <typename T>
check(T const & seq,char const * info)65 void check(T const& seq, char const* info)
66 {
67 test::measure<zip_accumulator<int> >(seq, 1);
68 std::cout << info << test::live_code << std::endl;
69 }
70
71 template <typename T>
measure(T const & seq,char const * info,long const repeats)72 void measure(T const& seq, char const* info, long const repeats)
73 {
74 std::cout
75 << info
76 << test::measure<zip_accumulator<int> >(seq, repeats)
77 << std::endl;
78 }
79 }
80
main()81 int main()
82 {
83 using namespace boost::fusion;
84
85 std::cout.setf(std::ios::scientific);
86
87 vector<
88 int, int, int
89 >
90 vsmall_1(BOOST_PP_ENUM_PARAMS(3,));
91
92 vector<
93 int, int, int
94 >
95 vsmall_2(BOOST_PP_ENUM_PARAMS(3,));
96
97 vector<
98 int, int, int, int, int, int, int, int, int, int
99 >
100 vmedium_1(BOOST_PP_ENUM_PARAMS(10,));
101
102 vector<
103 int, int, int, int, int, int, int, int, int, int
104 >
105 vmedium_2(BOOST_PP_ENUM_PARAMS(10,));
106
107 //~ vector<
108 //~ int, int, int, int, int, int, int, int, int, int
109 //~ , int, int, int, int, int, int, int, int, int, int
110 //~ , int, int, int, int, int, int, int, int, int, int
111 //~ >
112 //~ vbig_1(BOOST_PP_ENUM_PARAMS(30,));
113
114 //~ vector<
115 //~ int, int, int, int, int, int, int, int, int, int
116 //~ , int, int, int, int, int, int, int, int, int, int
117 //~ , int, int, int, int, int, int, int, int, int, int
118 //~ >
119 //~ vbig_2(BOOST_PP_ENUM_PARAMS(30,));
120
121 // first decide how many repetitions to measure
122 long repeats = 100;
123 double measured = 0;
124 while (measured < 2.0 && repeats <= 10000000)
125 {
126 repeats *= 10;
127
128 boost::timer time;
129
130 test::hammer<zip_accumulator<int> >(zip(vsmall_1, vsmall_2), repeats);
131 test::hammer<zip_accumulator<int> >(zip(vmedium_1, vmedium_2), repeats);
132 //~ test::hammer<zip_accumulator<int> >(zip(vbig_1, vbig_2), repeats);
133
134 measured = time.elapsed();
135 }
136
137 check(zip(vsmall_1, vsmall_2),
138 "small zip accumulated result: ");
139 check(zip(vmedium_1, vmedium_2),
140 "medium zip accumulated result: ");
141 //~ check(zip(vbig_1, vbig_2),
142 //~ "big zip accumulated result: ");
143
144 measure(zip(vsmall_1, vsmall_2),
145 "small zip time: ", repeats);
146 measure(zip(vmedium_1, vmedium_2),
147 "medium zip time: ", repeats);
148 //~ measure(zip(vbig_1, vbig_2),
149 //~ "big zip time: ", repeats);
150
151 // This is ultimately responsible for preventing all the test code
152 // from being optimized away. Change this to return 0 and you
153 // unplug the whole test's life support system.
154 return test::live_code != 0;
155 }
156