File: zip_efficiency.cpp

package info (click to toggle)
boost1.42 1.42.0-4
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 277,864 kB
  • ctags: 401,076
  • sloc: cpp: 1,235,659; xml: 74,142; ansic: 41,313; python: 26,756; sh: 11,840; cs: 2,118; makefile: 655; perl: 494; yacc: 456; asm: 353; csh: 6
file content (155 lines) | stat: -rw-r--r-- 4,570 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*=============================================================================
    Copyright (c) 2001-2006 Joel de Guzman

    Distributed under the Boost Software License, Version 1.0. (See accompanying 
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#include "measure.hpp"

//~ #define FUSION_MAX_VECTOR_SIZE 30

#include <boost/fusion/algorithm/iteration/accumulate.hpp>
#include <boost/fusion/algorithm/transformation/zip.hpp>
#include <boost/fusion/container/vector.hpp>
#include <boost/fusion/sequence/intrinsic/value_at.hpp>
#include <boost/fusion/sequence/intrinsic/at.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <iostream>

#ifdef _MSC_VER
// inline aggressively
# pragma inline_recursion(on) // turn on inline recursion
# pragma inline_depth(255)    // max inline depth
#endif

namespace
{
    struct zip_add
    {
        template<typename Lhs, typename Rhs>
        struct result
        {
            typedef typename 
                boost::remove_reference<
                    typename boost::fusion::result_of::value_at_c<Lhs, 0>::type 
                >::type
            type;
        };

        template<typename Lhs, typename Rhs>
        typename result<Lhs, Rhs>::type 
        operator()(const Lhs& lhs, const Rhs& rhs) const
        {
            return boost::fusion::at_c<0>(lhs) + boost::fusion::at_c<1>(lhs) + rhs;
        }
    };

    // Our Accumulator function
    template <typename T>
    struct zip_accumulator
    {
        zip_accumulator()
            : sum()
        {}
        
        template <typename Sequence>
        void operator()(Sequence const& seq)
        {
            this->sum += boost::fusion::accumulate(seq, 0, zip_add());
        }
        
        T sum;
    };
    
    template <typename T>
    void check(T const& seq, char const* info)
    {
        test::measure<zip_accumulator<int> >(seq, 1);
        std::cout << info << test::live_code << std::endl;
    }

    template <typename T>
    void measure(T const& seq, char const* info, long const repeats)
    {
        std::cout 
            << info
            << test::measure<zip_accumulator<int> >(seq, repeats)
            << std::endl;
    }
}

int main()
{
    using namespace boost::fusion;

    std::cout.setf(std::ios::scientific);

    vector<
        int, int, int
    > 
    vsmall_1(BOOST_PP_ENUM_PARAMS(3,));

    vector<
        int, int, int
    > 
    vsmall_2(BOOST_PP_ENUM_PARAMS(3,));

    vector<
        int, int, int, int, int, int, int, int, int, int
    > 
    vmedium_1(BOOST_PP_ENUM_PARAMS(10,));

    vector<
        int, int, int, int, int, int, int, int, int, int
    > 
    vmedium_2(BOOST_PP_ENUM_PARAMS(10,));

    //~ vector<
        //~ int, int, int, int, int, int, int, int, int, int
      //~ , int, int, int, int, int, int, int, int, int, int
      //~ , int, int, int, int, int, int, int, int, int, int
    //~ > 
    //~ vbig_1(BOOST_PP_ENUM_PARAMS(30,));

    //~ vector<
        //~ int, int, int, int, int, int, int, int, int, int
      //~ , int, int, int, int, int, int, int, int, int, int
      //~ , int, int, int, int, int, int, int, int, int, int
    //~ > 
    //~ vbig_2(BOOST_PP_ENUM_PARAMS(30,));

    // first decide how many repetitions to measure
    long repeats = 100;
    double measured = 0;
    while (measured < 2.0 && repeats <= 10000000)
    {
        repeats *= 10;
        
        boost::timer time;

        test::hammer<zip_accumulator<int> >(zip(vsmall_1, vsmall_2), repeats);
        test::hammer<zip_accumulator<int> >(zip(vmedium_1, vmedium_2), repeats);
        //~ test::hammer<zip_accumulator<int> >(zip(vbig_1, vbig_2), repeats);

        measured = time.elapsed();
    }

    check(zip(vsmall_1, vsmall_2),
        "small zip accumulated result:      ");
    check(zip(vmedium_1, vmedium_2),
        "medium zip accumulated result:     ");
    //~ check(zip(vbig_1, vbig_2),
        //~ "big zip accumulated result:        "); 

    measure(zip(vsmall_1, vsmall_2),
        "small zip time:                    ", repeats);
    measure(zip(vmedium_1, vmedium_2),
        "medium zip time:                   ", repeats);
    //~ measure(zip(vbig_1, vbig_2),
        //~ "big zip time:                      ", repeats);

    // This is ultimately responsible for preventing all the test code
    // from being optimized away.  Change this to return 0 and you
    // unplug the whole test's life support system.
    return test::live_code != 0;
}