Update of /cvsroot/boost/boost/libs/fusion/example/performance
In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv19289/performance

Modified Files:
        Jamfile 
Added Files:
        functional.cpp 
Log Message:
adds benchmark for functional components - draft version


--- NEW FILE: functional.cpp ---
/*=============================================================================
    Copyright (c) 2001-2006 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/sequence/container/list.hpp>
#include <boost/fusion/sequence/container/vector.hpp>
#include <boost/fusion/algorithm/iteration/fold.hpp>
#include <boost/fusion/functional/adapter/unfused_generic.hpp>
#include <boost/fusion/functional/adapter/unfused_rvalue_args.hpp>
#include <boost/fusion/functional/adapter/fused_function_object.hpp>
#include <boost/fusion/functional/adapter/unfused_typed.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());
        }

        template <class Seq> struct result
        {
            typedef int 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;
            }

            template <typename T0, typename T1> struct result
            {
                typedef int 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;
        } 

        template<typename T0 = void, typename T1 = void, typename T2 = void, 
            typename T3 = void>
        struct result
        {
            typedef int 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;
    }
    {
        typedef boost::fusion::vector<int,int,int,int> s;
        boost::fusion::unfused_typed<F,s> f;
        std::cout << "unfused_typed<F,s>                             " << 
call_unfused(f,res) << std::endl;
        total += res;
    }
    {
        boost::fusion::unfused_rvalue_args<F> f;
        std::cout << "unfused_rvalue_args<F>                         " << 
call_unfused(f,res) << std::endl;
        total += res;
    }
    {
        boost::fusion::unfused_generic<F> f;
        std::cout << "unfused_generic<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;
    }
    std::cout << std::endl << "Loopback:" << std::endl;
    {
        typedef boost::fusion::vector<int,int,int,int> s;
        boost::fusion::unfused_typed< boost::fusion::fused_function_object<U>, 
s > f;
        std::cout << "unfused_typed<fused_function_object<U>,s >     " << 
call_unfused(f,res) << std::endl;
        total += res;
    }
    {
        boost::fusion::unfused_rvalue_args< 
boost::fusion::fused_function_object<U> > f;
        std::cout << "unfused_rvalue_args<fused_function_object<U> > " << 
call_unfused(f,res) << std::endl;
        total += res;
    }
    {
        boost::fusion::unfused_generic< boost::fusion::fused_function_object<U> 
> f;
        std::cout << "unfused_generic<fused_function_object<U> >     " << 
call_unfused(f,res) << std::endl;
        total += res;
    }
    return total;
}

Index: Jamfile
===================================================================
RCS file: /cvsroot/boost/boost/libs/fusion/example/performance/Jamfile,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- Jamfile     14 Dec 2006 08:41:22 -0000      1.1
+++ Jamfile     15 Feb 2007 23:20:27 -0000      1.2
@@ -16,3 +16,5 @@
 
 exe sequence_efficiency : sequence_efficiency.cpp ;
 
+exe functional : functional.cpp ;
+


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Boost-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/boost-cvs

Reply via email to