forked from boostorg/fusion
updates + zip tests
[SVN r36087]
This commit is contained in:
@ -14,12 +14,11 @@
|
|||||||
#include <boost/fusion/sequence/container/vector.hpp>
|
#include <boost/fusion/sequence/container/vector.hpp>
|
||||||
#include <boost/fusion/sequence/container/list.hpp>
|
#include <boost/fusion/sequence/container/list.hpp>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <numeric>
|
#include <boost/preprocessor/stringize.hpp>
|
||||||
#include <functional>
|
#include <boost/preprocessor/enum.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cmath>
|
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
// inline aggressively
|
// inline aggressively
|
||||||
@ -60,120 +59,105 @@ namespace
|
|||||||
|
|
||||||
T sum;
|
T sum;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void check(T const& seq, char const* info)
|
||||||
|
{
|
||||||
|
test::measure<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<accumulator<int> >(seq, repeats)
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We'll initialize the sequences from numeric strings that
|
||||||
|
// pass through boost::lexical_cast to make sure that the
|
||||||
|
// compiler is not optimizing by replacing the computation
|
||||||
|
// with constant results computed at compile time.
|
||||||
|
#define INIT(z, n, text) boost::lexical_cast<int>(BOOST_PP_STRINGIZE(n))
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using namespace test;
|
|
||||||
using namespace boost::fusion;
|
using namespace boost::fusion;
|
||||||
|
|
||||||
|
std::cout.setf(std::ios::scientific);
|
||||||
|
|
||||||
vector<
|
vector<
|
||||||
int, int, int
|
int, int, int
|
||||||
>
|
>
|
||||||
vsmall(BOOST_PP_ENUM_PARAMS(3,));
|
vsmall(BOOST_PP_ENUM(3, INIT, _));
|
||||||
|
|
||||||
list<
|
list<
|
||||||
int, int, int
|
int, int, int
|
||||||
>
|
>
|
||||||
lsmall(BOOST_PP_ENUM_PARAMS(3,));
|
lsmall(BOOST_PP_ENUM(3, INIT, _));
|
||||||
|
|
||||||
vector<
|
vector<
|
||||||
int, int, int, int, int, int, int, int, int, int
|
int, int, int, int, int, int, int, int, int, int
|
||||||
>
|
>
|
||||||
vmid(BOOST_PP_ENUM_PARAMS(10,));
|
vmedium(BOOST_PP_ENUM(10, INIT, _));
|
||||||
|
|
||||||
list<
|
list<
|
||||||
int, int, int, int, int, int, int, int, int, int
|
int, int, int, int, int, int, int, int, int, int
|
||||||
>
|
>
|
||||||
lmid(BOOST_PP_ENUM_PARAMS(10,));
|
lmedium(BOOST_PP_ENUM(10, INIT, _));
|
||||||
|
|
||||||
vector<
|
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
|
, 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(BOOST_PP_ENUM_PARAMS(30,));
|
vbig(BOOST_PP_ENUM(30, INIT, _));
|
||||||
|
|
||||||
list<
|
list<
|
||||||
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
|
, 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
|
||||||
>
|
>
|
||||||
lbig(BOOST_PP_ENUM_PARAMS(30,));
|
lbig(BOOST_PP_ENUM(30, INIT, _));
|
||||||
|
|
||||||
// first decide how many repetitions to measure
|
// first decide how many repetitions to measure
|
||||||
long repeats = 100;
|
long repeats = 100;
|
||||||
double measured = 0;
|
double measured = 0;
|
||||||
while (measured < 1.0 && repeats <= 10000000)
|
while (measured < 2.0 && repeats <= 10000000)
|
||||||
{
|
{
|
||||||
repeats *= 10;
|
repeats *= 10;
|
||||||
|
|
||||||
boost::timer time;
|
boost::timer time;
|
||||||
|
|
||||||
hammer<accumulator<int> >(vsmall, repeats);
|
test::hammer<accumulator<int> >(vsmall, repeats);
|
||||||
hammer<accumulator<int> >(lsmall, repeats);
|
test::hammer<accumulator<int> >(lsmall, repeats);
|
||||||
hammer<accumulator<int> >(vmid, repeats);
|
test::hammer<accumulator<int> >(vmedium, repeats);
|
||||||
hammer<accumulator<int> >(lmid, repeats);
|
test::hammer<accumulator<int> >(lmedium, repeats);
|
||||||
hammer<accumulator<int> >(vbig, repeats);
|
test::hammer<accumulator<int> >(vbig, repeats);
|
||||||
hammer<accumulator<int> >(lbig, repeats);
|
test::hammer<accumulator<int> >(lbig, repeats);
|
||||||
|
|
||||||
measured = time.elapsed();
|
measured = time.elapsed();
|
||||||
}
|
}
|
||||||
|
|
||||||
measure<accumulator<int> >(vsmall, 1);
|
check(vsmall, "small vector accumulated result: ");
|
||||||
std::cout
|
check(lsmall, "small list accumulated result: ");
|
||||||
<< "small vector accumulated result: "
|
check(vmedium, "medium vector accumulated result: ");
|
||||||
<< live_code << std::endl;
|
check(lmedium, "medium list accumulated result: ");
|
||||||
measure<accumulator<int> >(lsmall, 1);
|
check(vbig, "big vector accumulated result: ");
|
||||||
std::cout
|
check(lbig, "big list accumulated result: ");
|
||||||
<< "small list accumulated result: "
|
|
||||||
<< live_code << std::endl;
|
|
||||||
measure<accumulator<int> >(vmid, 1);
|
|
||||||
std::cout
|
|
||||||
<< "medium vector accumulated result: "
|
|
||||||
<< live_code << std::endl;
|
|
||||||
measure<accumulator<int> >(lmid, 1);
|
|
||||||
std::cout
|
|
||||||
<< "medium list accumulated result: "
|
|
||||||
<< live_code << std::endl;
|
|
||||||
measure<accumulator<int> >(vbig, 1);
|
|
||||||
std::cout
|
|
||||||
<< "big vector accumulated result: "
|
|
||||||
<< live_code << std::endl;
|
|
||||||
measure<accumulator<int> >(lbig, 1);
|
|
||||||
std::cout
|
|
||||||
<< "big list accumulated result: "
|
|
||||||
<< live_code << std::endl;
|
|
||||||
|
|
||||||
std::cout.setf(std::ios::scientific);
|
measure(vsmall, "small vector time: ", repeats);
|
||||||
|
measure(lsmall, "small list time: ", repeats);
|
||||||
std::cout
|
measure(vmedium, "medium vector time: ", repeats);
|
||||||
<< "small vector time: "
|
measure(lmedium, "medium list time: ", repeats);
|
||||||
<< measure<accumulator<int> >(vsmall, repeats)
|
measure(vbig, "big vector time: ", repeats);
|
||||||
<< std::endl;
|
measure(lbig, "big list time: ", repeats);
|
||||||
std::cout
|
|
||||||
<< "small list time: "
|
|
||||||
<< measure<accumulator<int> >(lsmall, repeats)
|
|
||||||
<< std::endl;
|
|
||||||
std::cout
|
|
||||||
<< "medium vector time: "
|
|
||||||
<< measure<accumulator<int> >(vmid, repeats)
|
|
||||||
<< std::endl;
|
|
||||||
std::cout
|
|
||||||
<< "medium list time: "
|
|
||||||
<< measure<accumulator<int> >(lmid, repeats)
|
|
||||||
<< std::endl;
|
|
||||||
std::cout
|
|
||||||
<< "big vector time: "
|
|
||||||
<< measure<accumulator<int> >(vbig, repeats)
|
|
||||||
<< std::endl;
|
|
||||||
std::cout
|
|
||||||
<< "big list time: "
|
|
||||||
<< measure<accumulator<int> >(lbig, repeats)
|
|
||||||
<< std::endl;
|
|
||||||
|
|
||||||
// This is ultimately responsible for preventing all the test code
|
// This is ultimately responsible for preventing all the test code
|
||||||
// from being optimized away. Change this to return 0 and you
|
// from being optimized away. Change this to return 0 and you
|
||||||
// unplug the whole test's life support system.
|
// unplug the whole test's life support system.
|
||||||
return live_code != 0;
|
return test::live_code != 0;
|
||||||
}
|
}
|
||||||
|
@ -11,21 +11,21 @@ Tester: Joel de Guzman. WinXP, P4-3.0GHZ, 2GB RAM
|
|||||||
|
|
||||||
VC7.1 (flags = /MD /O2 /EHsc /GS)
|
VC7.1 (flags = /MD /O2 /EHsc /GS)
|
||||||
|
|
||||||
small vector time: 1.880000e-006
|
small vector time: 1.870000e-006
|
||||||
small list time: 2.040000e-006
|
small list time: 1.870000e-006
|
||||||
medium vector time: 2.030000e-006
|
medium vector time: 1.880000e-006
|
||||||
medium list time: 3.590000e-006
|
medium list time: 3.600000e-006
|
||||||
big vector time: 1.880000e-006
|
big vector time: 2.030000e-006
|
||||||
big list time: 9.070000e-006
|
big list time: 8.910000e-006
|
||||||
|
|
||||||
VC8.0 (flags = /MD /O2 /EHsc /GS)
|
VC8.0 (flags = /MD /O2 /EHsc /GS)
|
||||||
|
|
||||||
small vector time: 1.880000e-006
|
small vector time: 2.500000e-05
|
||||||
small list time: 2.030000e-006
|
small list time: 2.500000e-05
|
||||||
medium vector time: 2.030000e-006
|
medium vector time: 7.810000e-05
|
||||||
medium list time: 3.750000e-006
|
medium list time: 7.810000e-05
|
||||||
big vector time: 1.880000e-006
|
big vector time: 2.469000e-04
|
||||||
big list time: 9.380000e-006
|
big list time: 2.453000e-04
|
||||||
|
|
||||||
G++ 3.4 (flags = -ftemplate-depth-128 -funroll-loops -O3 -finline-functions -Wno-inline -Wall)
|
G++ 3.4 (flags = -ftemplate-depth-128 -funroll-loops -O3 -finline-functions -Wno-inline -Wall)
|
||||||
|
|
||||||
@ -38,12 +38,12 @@ G++ 3.4 (flags = -ftemplate-depth-128 -funroll-loops -O3 -finline-functions -Wn
|
|||||||
|
|
||||||
Intel 9.1 (flags = /MD /O2 /EHsc /GS)
|
Intel 9.1 (flags = /MD /O2 /EHsc /GS)
|
||||||
|
|
||||||
small vector time: 1.141000e-006
|
small vector time: 1.125000e-006
|
||||||
small list time: 1.156000e-006
|
small list time: 1.125000e-006
|
||||||
medium vector time: 1.156000e-006
|
medium vector time: 1.125000e-006
|
||||||
medium list time: 1.156000e-006
|
medium list time: 1.141000e-006
|
||||||
big vector time: 1.171000e-006
|
big vector time: 1.140000e-006
|
||||||
big list time: 1.156000e-006
|
big list time: 1.141000e-006
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
156
example/performance/zip_efficiency.cpp
Normal file
156
example/performance/zip_efficiency.cpp
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
/*=============================================================================
|
||||||
|
Copyright (c) 2001-2006 Joel de Guzman
|
||||||
|
|
||||||
|
Use, modification and distribution is subject to 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/sequence/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;
|
||||||
|
}
|
Reference in New Issue
Block a user