diff --git a/example/performance/sequence_efficiency.cpp b/example/performance/sequence_efficiency.cpp index e9515838..368a045a 100644 --- a/example/performance/sequence_efficiency.cpp +++ b/example/performance/sequence_efficiency.cpp @@ -14,12 +14,11 @@ #include #include -#include -#include -#include +#include +#include +#include + #include -#include -#include #ifdef _MSC_VER // inline aggressively @@ -60,120 +59,105 @@ namespace T sum; }; + + template + void check(T const& seq, char const* info) + { + test::measure >(seq, 1); + std::cout << info << test::live_code << std::endl; + } + + template + void measure(T const& seq, char const* info, long const repeats) + { + std::cout + << info + << test::measure >(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(BOOST_PP_STRINGIZE(n)) + int main() { - using namespace test; using namespace boost::fusion; + std::cout.setf(std::ios::scientific); + vector< int, int, int > - vsmall(BOOST_PP_ENUM_PARAMS(3,)); + vsmall(BOOST_PP_ENUM(3, INIT, _)); list< int, int, int > - lsmall(BOOST_PP_ENUM_PARAMS(3,)); + lsmall(BOOST_PP_ENUM(3, INIT, _)); vector< int, int, int, int, int, int, int, int, int, int > - vmid(BOOST_PP_ENUM_PARAMS(10,)); + vmedium(BOOST_PP_ENUM(10, INIT, _)); list< int, int, int, int, int, int, int, int, int, int > - lmid(BOOST_PP_ENUM_PARAMS(10,)); + lmedium(BOOST_PP_ENUM(10, INIT, _)); 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(BOOST_PP_ENUM_PARAMS(30,)); + vbig(BOOST_PP_ENUM(30, INIT, _)); 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 > - lbig(BOOST_PP_ENUM_PARAMS(30,)); + lbig(BOOST_PP_ENUM(30, INIT, _)); // first decide how many repetitions to measure long repeats = 100; double measured = 0; - while (measured < 1.0 && repeats <= 10000000) + while (measured < 2.0 && repeats <= 10000000) { repeats *= 10; boost::timer time; - hammer >(vsmall, repeats); - hammer >(lsmall, repeats); - hammer >(vmid, repeats); - hammer >(lmid, repeats); - hammer >(vbig, repeats); - hammer >(lbig, repeats); + test::hammer >(vsmall, repeats); + test::hammer >(lsmall, repeats); + test::hammer >(vmedium, repeats); + test::hammer >(lmedium, repeats); + test::hammer >(vbig, repeats); + test::hammer >(lbig, repeats); measured = time.elapsed(); } - measure >(vsmall, 1); - std::cout - << "small vector accumulated result: " - << live_code << std::endl; - measure >(lsmall, 1); - std::cout - << "small list accumulated result: " - << live_code << std::endl; - measure >(vmid, 1); - std::cout - << "medium vector accumulated result: " - << live_code << std::endl; - measure >(lmid, 1); - std::cout - << "medium list accumulated result: " - << live_code << std::endl; - measure >(vbig, 1); - std::cout - << "big vector accumulated result: " - << live_code << std::endl; - measure >(lbig, 1); - std::cout - << "big list accumulated result: " - << live_code << std::endl; + check(vsmall, "small vector accumulated result: "); + check(lsmall, "small list accumulated result: "); + check(vmedium, "medium vector accumulated result: "); + check(lmedium, "medium list accumulated result: "); + check(vbig, "big vector accumulated result: "); + check(lbig, "big list accumulated result: "); - std::cout.setf(std::ios::scientific); - - std::cout - << "small vector time: " - << measure >(vsmall, repeats) - << std::endl; - std::cout - << "small list time: " - << measure >(lsmall, repeats) - << std::endl; - std::cout - << "medium vector time: " - << measure >(vmid, repeats) - << std::endl; - std::cout - << "medium list time: " - << measure >(lmid, repeats) - << std::endl; - std::cout - << "big vector time: " - << measure >(vbig, repeats) - << std::endl; - std::cout - << "big list time: " - << measure >(lbig, repeats) - << std::endl; + measure(vsmall, "small vector time: ", repeats); + measure(lsmall, "small list time: ", repeats); + measure(vmedium, "medium vector time: ", repeats); + measure(lmedium, "medium list time: ", repeats); + measure(vbig, "big vector time: ", repeats); + measure(lbig, "big list 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 live_code != 0; + return test::live_code != 0; } diff --git a/example/performance/timings.txt b/example/performance/timings.txt index af383d87..0ab51e55 100644 --- a/example/performance/timings.txt +++ b/example/performance/timings.txt @@ -11,21 +11,21 @@ Tester: Joel de Guzman. WinXP, P4-3.0GHZ, 2GB RAM VC7.1 (flags = /MD /O2 /EHsc /GS) - small vector time: 1.880000e-006 - small list time: 2.040000e-006 - medium vector time: 2.030000e-006 - medium list time: 3.590000e-006 - big vector time: 1.880000e-006 - big list time: 9.070000e-006 + small vector time: 1.870000e-006 + small list time: 1.870000e-006 + medium vector time: 1.880000e-006 + medium list time: 3.600000e-006 + big vector time: 2.030000e-006 + big list time: 8.910000e-006 VC8.0 (flags = /MD /O2 /EHsc /GS) - small vector time: 1.880000e-006 - small list time: 2.030000e-006 - medium vector time: 2.030000e-006 - medium list time: 3.750000e-006 - big vector time: 1.880000e-006 - big list time: 9.380000e-006 + small vector time: 2.500000e-05 + small list time: 2.500000e-05 + medium vector time: 7.810000e-05 + medium list time: 7.810000e-05 + big vector time: 2.469000e-04 + big list time: 2.453000e-04 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) - small vector time: 1.141000e-006 - small list time: 1.156000e-006 - medium vector time: 1.156000e-006 - medium list time: 1.156000e-006 - big vector time: 1.171000e-006 - big list time: 1.156000e-006 + small vector time: 1.125000e-006 + small list time: 1.125000e-006 + medium vector time: 1.125000e-006 + medium list time: 1.141000e-006 + big vector time: 1.140000e-006 + big list time: 1.141000e-006 diff --git a/example/performance/zip_efficiency.cpp b/example/performance/zip_efficiency.cpp new file mode 100644 index 00000000..8cea77cf --- /dev/null +++ b/example/performance/zip_efficiency.cpp @@ -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 +#include +#include +#include +#include +#include +#include + +#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 + struct result + { + typedef typename + boost::remove_reference< + typename boost::fusion::result_of::value_at_c::type + >::type + type; + }; + + template + typename result::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 + struct zip_accumulator + { + zip_accumulator() + : sum() + {} + + template + void operator()(Sequence const& seq) + { + this->sum += boost::fusion::accumulate(seq, 0, zip_add()); + } + + T sum; + }; + + template + void check(T const& seq, char const* info) + { + test::measure >(seq, 1); + std::cout << info << test::live_code << std::endl; + } + + template + void measure(T const& seq, char const* info, long const repeats) + { + std::cout + << info + << test::measure >(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(vsmall_1, vsmall_2), repeats); + test::hammer >(zip(vmedium_1, vmedium_2), repeats); + //~ test::hammer >(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; +}