[ create a new paste ] login | about

Link: http://codepad.org/rRX33dgR    [ raw code | output | fork ]

manuelj_pg - C++, pasted on Feb 11:
#include <boost/variant.hpp>
#include <boost/any.hpp>
#include <ctime>
#include <iostream>
#include <memory>

namespace use_var
{
    struct NoIntersection {
        // empty
    };
    struct Point { 
        int x, y;
        Point(int x,int y) : x(x),y(y) {}
    };
    struct Circle { 
        Point c;
        int r;
        Circle(Point const & c, int r) : c(c), r(r) {}
    };

    typedef boost::variant<NoIntersection, Point, Circle> IntersectionResult;

    IntersectionResult intersection_test(int i) {

        if(i % 2 == 0){ 
            return NoIntersection();
        }
        if(i % 3 == 0){ 
            return Point(i, i * 2);
        }
        return Circle(Point(i, i * 2), i * 3);
    }

    struct process_result_visitor : public boost::static_visitor<> {

        int results[3];
        process_result_visitor() { results[0] = results[1] = results[2] = 0; }

        void operator()(NoIntersection) {
            ++results[0];
        }
        void operator()(Point const &) {
            ++results[1];
        }
        void operator()(Circle const &) {
            ++results[2];
        }
    };

    double do_test(int N) // returns time in microseconds
    {
        std::clock_t const start = std::clock();
        process_result_visitor processor;
        for(int i = 0; i < N; ++i)
        {
            IntersectionResult result = intersection_test(i);
            boost::apply_visitor(processor, result);
        }
        std::clock_t const end = std::clock(); 
        return (double(end - start) / N) / CLOCKS_PER_SEC * 1e6;
    }
}

namespace use_union
{
    struct NoIntersection {
        // empty
    };
    struct Point { 
        int x, y;
    };
    struct Circle { 
        Point c;
        int r;
    };
    struct IntersectionResult
    {
        enum Type { NoInter, PointInter, CircleInter };
        Type type;
        union
        {
            Point p;
            Circle c;
        } data;
    };

    IntersectionResult intersection_test(int i) {

        IntersectionResult result;
        if(i % 2 == 0){ 
            result.type = IntersectionResult::NoInter;
        }
        else if(i % 3 == 0){ 
            result.type = IntersectionResult::PointInter;
            Point p = { i, i * 2 };
            result.data.p = p;
        }
        else {
            result.type = IntersectionResult::PointInter;
            Circle c = { { i, i * 2 }, i * 3 };
            result.data.c = c;
        }
        return result;
    }

    struct result_processor {

        int results[3];
        result_processor() { results[0] = results[1] = results[2] = 0; }

        void operator()(IntersectionResult const & result) {
            ++results[result.type];
        }
    };

    double do_test(int N) // returns time in microseconds
    {
        std::clock_t const start = std::clock();
        result_processor processor;
        for(int i = 0; i < N; ++i)
        {
            IntersectionResult result = intersection_test(i);
            processor(result);
        }
        std::clock_t const end = std::clock(); 
        return (double(end - start) / N) / CLOCKS_PER_SEC * 1e6;
    }
}

namespace use_hierarchy
{
    struct IntersectionResult
    {
        virtual ~IntersectionResult() { }
    };
    struct NoIntersection : public IntersectionResult {
        // empty
    };
    struct Point : public IntersectionResult { 
        int x, y;
        Point(int x,int y) : x(x),y(y) {}
    };
    struct Circle : public IntersectionResult { 
        Point c;
        int r;
        Circle(Point const & c, int r) : c(c), r(r) {}
    };

    std::auto_ptr<IntersectionResult> intersection_test(int i) {

        if(i % 2 == 0){ 
            return std::auto_ptr<IntersectionResult>(new NoIntersection);
        }
        if(i % 3 == 0){ 
            return std::auto_ptr<IntersectionResult>(new Point(i, i * 2));
        }
        return std::auto_ptr<IntersectionResult>(new Circle(Point(i, i * 2), i * 3));        
    }
    
    struct result_processor {

        int results[3];
        result_processor() { results[0] = results[1] = results[2] = 0; }

        void operator()(IntersectionResult const & result) {
            if(dynamic_cast<NoIntersection const *>(&result))
                ++results[0];
            else if(dynamic_cast<Point const *>(&result))
                ++results[1];
            else 
                ++results[2];
        }
    };

    double do_test(int N) // returns time in microseconds
    {
        std::clock_t const start = std::clock();
        result_processor processor;
        for(int i = 0; i < N; ++i)
        {
            std::auto_ptr<IntersectionResult> result(intersection_test(i));
            processor(*result);
        }
        std::clock_t const end = std::clock(); 
        return (double(end - start) / N) / CLOCKS_PER_SEC * 1e6;
    }
}

namespace use_any
{
    using use_var::NoIntersection;
    using use_var::Point;
    using use_var::Circle;
    typedef boost::any IntersectionResult;
    using use_var::intersection_test;
    
    struct result_processor {

        int results[3];
        result_processor() { results[0] = results[1] = results[2] = 0; }

        void operator()(IntersectionResult const & result) {
            
            if(result.type() == typeid(NoIntersection))
                ++results[0];
            else if(result.type() == typeid(Point))
                ++results[1];
            else 
                ++results[2];
        }
    };

    double do_test(int N) // returns time in microseconds
    {
        std::clock_t const start = std::clock();
        result_processor processor;
        for(int i = 0; i < N; ++i)
        {
            IntersectionResult result(intersection_test(i));
            processor(result);
        }
        std::clock_t const end = std::clock(); 
        return (double(end - start) / N) / CLOCKS_PER_SEC * 1e6;
    }
}

int main()
{
    int const N = 1000000;

    double use_var_time = use_var::do_test(N);
    std::cout << "test with boost::variant took " << use_var_time << " microseconds\n";
    
    double use_union_time = use_var::do_test(N);
    std::cout << "test with union took " << use_union_time << " microseconds\n";

    double use_hierarchy_time = use_hierarchy::do_test(N);
    std::cout << "test with hierarchy took " << use_hierarchy_time << " microseconds\n";

    double use_any_time = use_any::do_test(N);
    std::cout << "test with boost::any took " << use_any_time << " microseconds\n";

    return 0;
}


Output:
1
2
3
4
test with boost::variant took 0.03 microseconds
test with union took 0.05 microseconds
test with hierarchy took 0.11 microseconds
test with boost::any took 0.16 microseconds


Create a new paste based on this one


Comments: