• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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