123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 |
- /*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2006-2007 Tobias Schwinger
-
- Use modification and distribution are 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 <boost/fusion/container/list.hpp>
- #include <boost/fusion/container/vector.hpp>
- #include <boost/fusion/algorithm/iteration/fold.hpp>
- #include <boost/fusion/functional/adapter/unfused.hpp>
- #include <boost/fusion/functional/adapter/fused_function_object.hpp>
- #include <boost/functional/forward_adapter.hpp>
- #include <boost/functional/lightweight_forward_adapter.hpp>
- #include <boost/utility/result_of.hpp>
- #include <boost/config.hpp>
- #include <boost/timer.hpp>
- #include <algorithm>
- #include <iostream>
- #ifdef _MSC_VER
- // inline aggressively
- # pragma inline_recursion(on) // turn on inline recursion
- # pragma inline_depth(255) // max inline depth
- #endif
- int const REPEAT_COUNT = 3;
- double const duration = 0.125;
- namespace
- {
- struct fused_sum
- {
- template <typename Seq>
- int operator()(Seq const & seq) const
- {
- int state = 0;
- return boost::fusion::fold(seq, state, sum_op());
- }
- typedef int result_type;
- private:
- struct sum_op
- {
- template <typename T>
- int operator()(T const & elem, int value) const
- {
- return value + sizeof(T) * elem;
- }
- template <typename T>
- int operator()(T & elem, int value) const
- {
- elem += sizeof(T);
- return value;
- }
- typedef int result_type;
- };
- };
- struct unfused_sum
- {
- inline int operator()() const
- {
- return 0;
- }
- template<typename T0>
- inline int operator()(T0 const & a0) const
- {
- return a0;
- }
- template<typename T0, typename T1>
- inline int operator()(T0 const & a0, T1 const & a1) const
- {
- return a0 + a1;
- }
- template<typename T0, typename T1, typename T2>
- inline int operator()(T0 const & a0, T1 const & a1, T2 a2) const
- {
- return a0 + a1 + a2;
- }
- template<typename T0, typename T1, typename T2, typename T3>
- inline int operator()(T0 const & a0, T1 const & a1, T2 const & a2, T3 const & a3) const
- {
- return a0 + a1 + a2 + a3;
- }
- typedef int result_type;
- };
- template<typename F>
- double call_unfused(F const & func, int & j)
- {
- boost::timer tim;
- int i = 0;
- long long iter = 65536;
- long long counter, repeats;
- double result = (std::numeric_limits<double>::max)();
- double runtime = 0;
- double run;
- do
- {
- tim.restart();
- for(counter = 0; counter < iter; ++counter)
- {
- i += func();
- i += func(0);
- i += func(0,1);
- i += func(0,1,2);
- i += func(0,1,2,3);
- }
- runtime = tim.elapsed();
- iter *= 2;
- } while(runtime < duration);
- iter /= 2;
- for(repeats = 0; repeats < REPEAT_COUNT; ++repeats)
- {
- tim.restart();
- for(counter = 0; counter < iter; ++counter)
- {
- i = func(); j += i;
- i = func(0); j += i;
- i = func(0,1); j += i;
- i = func(0,1,2); j += i;
- i = func(0,1,2,3); j += i;
- }
- run = tim.elapsed();
- result = (std::min)(run, result);
- }
- return result / iter;
- }
- template<typename F>
- double call_fused_ra(F const & func, int & j)
- {
- boost::timer tim;
- int i = 0;
- long long iter = 65536;
- long long counter, repeats;
- double result = (std::numeric_limits<double>::max)();
- double runtime = 0;
- double run;
- do
- {
- boost::fusion::vector<> v0;
- boost::fusion::vector<int> v1(0);
- boost::fusion::vector<int,int> v2(0,1);
- boost::fusion::vector<int,int,int> v3(0,1,2);
- boost::fusion::vector<int,int,int,int> v4(0,1,2,3);
- tim.restart();
- for(counter = 0; counter < iter; ++counter)
- {
- i += func(v0);
- i += func(v1);
- i += func(v2);
- i += func(v3);
- i += func(v4);
- }
- runtime = tim.elapsed();
- iter *= 2;
- } while(runtime < duration);
- iter /= 2;
- for(repeats = 0; repeats < REPEAT_COUNT; ++repeats)
- {
- boost::fusion::vector<> v0;
- boost::fusion::vector<int> v1(0);
- boost::fusion::vector<int,int> v2(0,1);
- boost::fusion::vector<int,int,int> v3(0,1,2);
- boost::fusion::vector<int,int,int,int> v4(0,1,2,3);
- tim.restart();
- for(counter = 0; counter < iter; ++counter)
- {
- i = func(v0); j += i;
- i = func(v1); j += i;
- i = func(v2); j += i;
- i = func(v3); j += i;
- i = func(v4); j += i;
- }
- run = tim.elapsed();
- result = (std::min)(run, result);
- }
- return result / iter;
- }
- template<typename F>
- double call_fused(F const & func, int & j)
- {
- boost::timer tim;
- int i = 0;
- long long iter = 65536;
- long long counter, repeats;
- double result = (std::numeric_limits<double>::max)();
- double runtime = 0;
- double run;
- do
- {
- boost::fusion::list<> l0;
- boost::fusion::list<int> l1(0);
- boost::fusion::list<int,int> l2(0,1);
- boost::fusion::list<int,int,int> l3(0,1,2);
- boost::fusion::list<int,int,int,int> l4(0,1,2,3);
- tim.restart();
- for(counter = 0; counter < iter; ++counter)
- {
- i += func(l0);
- i += func(l1);
- i += func(l2);
- i += func(l3);
- i += func(l4);
- }
- runtime = tim.elapsed();
- iter *= 2;
- } while(runtime < duration);
- iter /= 2;
- for(repeats = 0; repeats < REPEAT_COUNT; ++repeats)
- {
- boost::fusion::list<> l0;
- boost::fusion::list<int> l1(0);
- boost::fusion::list<int,int> l2(0,1);
- boost::fusion::list<int,int,int> l3(0,1,2);
- boost::fusion::list<int,int,int,int> l4(0,1,2,3);
- tim.restart();
- for(counter = 0; counter < iter; ++counter)
- {
- i = func(l0); j += i;
- i = func(l1); j += i;
- i = func(l2); j += i;
- i = func(l3); j += i;
- i = func(l4); j += i;
- }
- run = tim.elapsed();
- result = (std::min)(run, result);
- }
- return result / iter;
- }
- }
- int main()
- {
- int total = 0;
- int res;
- typedef fused_sum F;
- typedef unfused_sum U;
- std::cout << "Compiler: " << BOOST_COMPILER << std::endl;
- std::cout << std::endl << "Unfused adapters:" << std::endl;
- {
- F f;
- std::cout << "F /* a fused function object */ " << call_fused_ra(f,res) << std::endl;
- total += res;
- }
- {
- F f;
- std::cout << "without random access " << call_fused(f,res) << std::endl;
- total += res;
- }
- {
- boost::lightweight_forward_adapter< boost::fusion::unfused<F> > f;
- std::cout << "lightweight_forward_adapter< unfused<F> > " << call_unfused(f,res) << std::endl;
- total += res;
- }
- {
- boost::forward_adapter< boost::fusion::unfused<F> > f;
- std::cout << "forward_adapter< unfused<F> > " << call_unfused(f,res) << std::endl;
- total += res;
- }
- std::cout << std::endl << "Fused adapters:" << std::endl;
- {
- unfused_sum f;
- std::cout << "U /* an unfused function object */ " << call_unfused(f,res) << std::endl;
- total += res;
- }
- {
- boost::fusion::fused_function_object<U> f;
- std::cout << "fused_function_object<U> " << call_fused_ra(f,res) << std::endl;
- total += res;
- }
- {
- boost::fusion::fused_function_object<U> f;
- std::cout << "without random access " << call_fused(f,res) << std::endl;
- total += res;
- }
- {
- boost::lightweight_forward_adapter< boost::fusion::unfused< boost::fusion::fused_function_object<U> > > f;
- std::cout << "lightweight_forward_adapter< unfused<fused_function_object<U> > >" << call_unfused(f,res) << std::endl;
- total += res;
- }
- {
- boost::forward_adapter< boost::fusion::unfused< boost::fusion::fused_function_object<U> > > f;
- std::cout << "forward_adapter< unfused<fused_function_object<U> > > " << call_unfused(f,res) << std::endl;
- total += res;
- }
-
- return total;
- }
|