#include #include #include #include #include #include #include #include #include "auto_cpu_timer.hpp" #include #include #define TEXT_SHORT "Test" #define TEXT_LONG "Testing various variant implementations with a longish string ........................................." #define NUM_SAMPLES 3 //#define BOOST_VARIANT_MINIMIZE_SIZE using namespace mapbox; namespace test { template struct Holder { typedef V value_type; std::vector data; template void append_move(T&& obj) { data.emplace_back(std::forward(obj)); } template void append(T const& obj) { data.push_back(obj); } }; } // namespace test struct print { template void operator()(T const& val) const { std::cerr << val << ":" << typeid(T).name() << std::endl; } }; template struct dummy : boost::static_visitor<> { dummy(V& v) : v_(v) {} template void operator()(T&& val) const { v_ = std::move(val); } V& v_; }; template struct dummy2 { dummy2(V& v) : v_(v) {} template void operator()(T&& val) const { v_ = std::move(val); } V& v_; }; void run_boost_test(std::size_t runs) { test::Holder> h; h.data.reserve(runs); for (std::size_t i = 0; i < runs; ++i) { h.append_move(std::string(TEXT_SHORT)); h.append_move(std::string(TEXT_LONG)); h.append_move(123); h.append_move(3.14159); } boost::variant v; for (auto const& v2 : h.data) { dummy> d(v); boost::apply_visitor(d, v2); } } void run_variant_test(std::size_t runs) { test::Holder> h; h.data.reserve(runs); for (std::size_t i = 0; i < runs; ++i) { h.append_move(std::string(TEXT_SHORT)); h.append_move(std::string(TEXT_LONG)); h.append_move(123); h.append_move(3.14159); } util::variant v; for (auto const& v2 : h.data) { dummy2> d(v); util::apply_visitor(d, v2); } } int main(int argc, char** argv) { if (argc != 2) { std::cerr << "Usage:" << argv[0] << " " << std::endl; return 1; } #ifndef SINGLE_THREADED const std::size_t THREADS = 4; #endif const std::size_t NUM_RUNS = static_cast(std::stol(argv[1])); #ifdef SINGLE_THREADED for (std::size_t j = 0; j < NUM_SAMPLES; ++j) { { std::cerr << "custom variant: "; auto_cpu_timer t; run_variant_test(NUM_RUNS); } { std::cerr << "boost variant: "; auto_cpu_timer t; run_boost_test(NUM_RUNS); } } #else for (std::size_t j = 0; j < NUM_SAMPLES; ++j) { { typedef std::vector> thread_group; typedef thread_group::value_type value_type; thread_group tg; std::cerr << "custom variant: "; auto_cpu_timer timer; for (std::size_t i = 0; i < THREADS; ++i) { tg.emplace_back(new std::thread(run_variant_test, NUM_RUNS)); } std::for_each(tg.begin(), tg.end(), [](value_type& t) {if (t->joinable()) t->join(); }); } { typedef std::vector> thread_group; typedef thread_group::value_type value_type; thread_group tg; std::cerr << "boost variant: "; auto_cpu_timer timer; for (std::size_t i = 0; i < THREADS; ++i) { tg.emplace_back(new std::thread(run_boost_test, NUM_RUNS)); } std::for_each(tg.begin(), tg.end(), [](value_type& t) {if (t->joinable()) t->join(); }); } } #endif return EXIT_SUCCESS; }