/*============================================================================= Copyright (c) 2006 Eric Niebler 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) ==============================================================================*/ #define FUSION_MAX_VECTOR_SIZE 25 #ifdef _MSC_VER // inline aggressively # pragma inline_recursion(on) // turn on inline recursion # pragma inline_depth(255) // max inline depth #endif #include #include #include #include #include #include #include namespace test { struct accumulator : boost::static_visitor<> { accumulator(int &i_) : i(i_) {} template void operator()(T const &t) const { this->i += t; } int &i; }; struct variant_accumulator { variant_accumulator(int &i_) : i(i_) {} template void operator()(Variant const& v) const { boost::apply_visitor( accumulator(i), v ); } int &i; }; int const REPEAT_COUNT = 10; template double time_for_each_variant(T const &t, int &j) { boost::timer tim; int i = 0; long long iter = 65536; long long counter, repeats; double result = 0; double run; do { tim.restart(); for(counter = 0; counter < iter; ++counter) { i = 0; std::for_each(t.begin(), t.end(), variant_accumulator(i)); static_cast(i); } result = tim.elapsed(); iter *= 2; } while(result < 0.5); iter /= 2; // repeat test and report least value for consistency: for(repeats = 0; repeats < REPEAT_COUNT; ++repeats) { tim.restart(); for(counter = 0; counter < iter; ++counter) { i = 0; std::for_each(t.begin(), t.end(), variant_accumulator(i)); j += i; } run = tim.elapsed(); result = (std::min)(run, result); } std::cout << i << std::endl; return result / iter; } template double time_for_each_fusion(T const &t, int &j) { boost::timer tim; int i = 0; long long iter = 65536; long long counter, repeats; double result = 0; double run; do { tim.restart(); for(counter = 0; counter < iter; ++counter) { i = 0; boost::fusion::for_each(t, accumulator(i)); static_cast(i); } result = tim.elapsed(); iter *= 2; } while(result < 0.5); iter /= 2; // repeat test and report least value for consistency: for(repeats = 0; repeats < REPEAT_COUNT; ++repeats) { tim.restart(); for(counter = 0; counter < iter; ++counter) { i = 0; boost::fusion::for_each(t, accumulator(i)); j += i; } run = tim.elapsed(); result = (std::min)(run, result); } std::cout << i << std::endl; return result / iter; } int test_short() { int j = 0; typedef int T0; typedef char T1; typedef short T2; typedef long T3; typedef boost::fusion::vector fusion_vector_type; fusion_vector_type const l(3,42,6,29); double fusion_time = time_for_each_fusion( l, j ); typedef boost::variant variant_type; std::vector v; v.push_back(3); v.push_back(42); v.push_back(6); v.push_back(29); double variant_time = time_for_each_variant( v, j ); std::cout << "Fusion vector size : " << sizeof(fusion_vector_type) << std::endl; std::cout << "Variant vector size (includes vector size + data) : " << (sizeof(variant_type)*4)+sizeof(v) << std::endl; std::cout << "Fusion vector time : " << fusion_time << std::endl; std::cout << "Variant time : " << variant_time << std::endl; return j; } int test_long() { int j = 0; typedef int T0; typedef char T1; typedef short T2; typedef long T3; boost::fusion::vector const l( 3,42,6,29 ,3,42,6,29 ,3,42,6,29 ,3,42,6,29 ,3,42,6,29 ,3,42,6,29); double fusion_time = time_for_each_fusion( l, j ); typedef boost::variant variant_type; std::vector v; for (int i = 0; i < 6; ++i) { v.push_back(3); v.push_back(42); v.push_back(6); v.push_back(29); } double variant_time = time_for_each_variant( v, j ); std::cout << "Fusion vector time : " << fusion_time << std::endl; std::cout << "Variant time : " << variant_time << std::endl; return j; } } int main() { std::cout << "Short test ... \n"; int i = test::test_short(); std::cout << "Long test ... \n"; int j = test::test_long(); return i + j; }