123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- // (C) Copyright Tobias Schwinger
- //
- // Use modification and distribution are subject to the boost Software License,
- // Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
- //------------------------------------------------------------------------------
- // See fast_mem_fn.hpp in this directory for details.
- #include <vector>
- #include <cassert>
- #include <iostream>
- #include <algorithm>
- #include <functional>
- #include <boost/timer.hpp>
- #include <boost/mem_fn.hpp>
- #include "fast_mem_fn.hpp"
- // test class that holds a single integer with getter function
- class test
- {
- int val_id;
- public:
- explicit test(int id)
- : val_id(id)
- { }
- int id() const
- { return val_id; }
- };
- // STL style comparator that applies the CriterionExtractor function to both
- // operands and compares the results with Comparator
- template<typename CriterionExtractor, typename Comparator>
- class test_compare
- {
- CriterionExtractor fnc_criterion;
- Comparator fnc_compare;
- public:
- explicit test_compare(CriterionExtractor criterion, Comparator compare)
- : fnc_criterion(criterion)
- , fnc_compare(compare)
- { }
- template<typename T>
- inline bool operator()(T const & lhs, T const & rhs) const
- {
- return fnc_compare(fnc_criterion(lhs),fnc_criterion(rhs));
- }
- };
- // helper function to construct an instance of the test_compare comparator.
- template<typename CriterionExtractor, typename Comparator>
- test_compare<CriterionExtractor,Comparator>
- make_test_compare(CriterionExtractor criterion, Comparator compare)
- {
- return test_compare<CriterionExtractor,Comparator>(criterion,compare);
- }
- // the test case: sort N test objects by id
- //
- // the objects are in ascending order before the test run and in descending
- // order after it
- static const unsigned N = 2000000;
- typedef std::vector<test> test_vector;
- void setup_test(test_vector & v)
- {
- v.clear();
- v.reserve(N);
- for (unsigned i = 0; i < N; ++i)
- v.push_back(test(i));
- }
- template<typename F> void do_test(test_vector & v, F criterion)
- {
- std::sort(v.begin(),v.end(),make_test_compare(criterion,std::greater<int>()));
- assert(v.begin()->id() == N-1);
- }
- // compare performance with boost::mem_fn
- int main()
- {
- test_vector v;
- boost::timer t;
- double time1, time2;
- std::cout <<
- "Test case: sorting " << N << " objects.\n\n"
- "Criterion accessor called with | elasped seconds\n"
- "-------------------------------|----------------" << std::endl;
- setup_test(v);
- t.restart();
- #if !BOOST_WORKAROUND(BOOST_MSVC, < 1400)
- do_test(v, BOOST_EXAMPLE_FAST_MEM_FN(& test::id));
- #else // MSVC<8 does not like the implementation of the deduction macro:
- do_test(v, ::example::fast_mem_fn< int (test::*)() const, & test::id >());
- #endif
- time1 = t.elapsed();
- std::cout << "fast_mem_fn | " << time1 << std::endl;
- setup_test(v);
- t.restart();
- do_test(v, boost::mem_fn(& test::id));
- time2 = t.elapsed();
- std::cout << "mem_fn | " << time2 << std::endl;
- std::cout << '\n' << (time2/time1-1)*100 << "% speedup" << std::endl;
- return 0;
- }
|