// (C) Copyright Antony Polukhin 2012-2014. // 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) // See http://www.boost.org/libs/config for most recent version. // // Testing variant performance rvalue copy/assign performance // #define BOOST_ERROR_CODE_HEADER_ONLY #define BOOST_CHRONO_HEADER_ONLY #include #include #include #include struct scope { typedef boost::chrono::steady_clock test_clock; typedef boost::chrono::milliseconds duration_t; test_clock::time_point start_; const char* const message_; explicit scope(const char* const message) : start_(test_clock::now()) , message_(message) {} ~scope() { std::cout << message_ << " " << boost::chrono::duration_cast(test_clock::now() - start_) << std::endl; } }; static void do_test(bool do_count_cleanup_time = false) { BOOST_STATIC_CONSTANT(std::size_t, c_run_count = 5000000); typedef std::vector str_t; typedef boost::variant var_t; const char hello1_c[] = "hello long word"; const str_t hello1(hello1_c, hello1_c + sizeof(hello1_c)); const char hello2_c[] = "Helllloooooooooooooooooooooooooooooooo!!!!!!!!!!!!!"; const str_t hello2(hello2_c, hello2_c + sizeof(hello2_c)); if (do_count_cleanup_time) { std::cout << "#############################################\n"; std::cout << "#############################################\n"; std::cout << "NOW TIMES WITH DATA DESTRUCTION\n"; std::cout << "#############################################\n"; } std::vector data_from, data_to; data_from.resize(c_run_count, hello1); data_to.reserve(c_run_count); { scope sc("boost::variant(const variant&) copying speed"); for (std::size_t i = 0; i < c_run_count; ++i) { data_to.push_back(data_from[i]); } if (do_count_cleanup_time) { data_to.clear(); data_from.clear(); } } data_from.resize(c_run_count, hello1); data_to.clear(); data_to.reserve(c_run_count); { scope sc("boost::variant(variant&&) moving speed"); for (std::size_t i = 0; i < c_run_count; ++i) { data_to.push_back(boost::move(data_from[i])); } if (do_count_cleanup_time) { data_to.clear(); data_from.clear(); } } std::cout << "#############################################\n"; data_from.clear(); data_from.resize(c_run_count, hello2); data_to.clear(); data_to.resize(c_run_count, hello2); { scope sc("boost::variant=(const variant&) copying speed on same types"); for (std::size_t i = 0; i < c_run_count; ++i) { data_to[i] = data_from[i]; } if (do_count_cleanup_time) { data_to.clear(); data_from.clear(); } } data_from.resize(c_run_count, hello2); data_to.clear(); data_to.resize(c_run_count, hello2); { scope sc("boost::variant=(variant&&) moving speed on same types"); for (std::size_t i = 0; i < c_run_count; ++i) { data_to[i] = boost::move(data_from[i]); } if (do_count_cleanup_time) { data_to.clear(); data_from.clear(); } } std::cout << "#############################################\n"; data_from.clear(); data_from.resize(c_run_count, hello2); data_to.clear(); data_to.resize(c_run_count, var_t(0)); { scope sc("boost::variant=(const variant&) copying speed on different types"); for (std::size_t i = 0; i < c_run_count; ++i) { data_to[i] = data_from[i]; } if (do_count_cleanup_time) { data_to.clear(); data_from.clear(); } } data_from.resize(c_run_count, hello2); data_to.clear(); data_to.resize(c_run_count, var_t(0)); { scope sc("boost::variant=(variant&&) moving speed on different types"); for (std::size_t i = 0; i < c_run_count; ++i) { data_to[i] = boost::move(data_from[i]); } if (do_count_cleanup_time) { data_to.clear(); data_from.clear(); } } std::cout << "#############################################\n"; data_from.clear(); data_from.resize(c_run_count, var_t(0)); data_to.clear(); data_to.resize(c_run_count, hello2); { scope sc("boost::variant=(const variant&) copying speed on different types II"); for (std::size_t i = 0; i < c_run_count; ++i) { data_to[i] = data_from[i]; } if (do_count_cleanup_time) { data_to.clear(); data_from.clear(); } } data_from.resize(c_run_count, var_t(0)); data_to.clear(); data_to.resize(c_run_count, hello2); { scope sc("boost::variant=(variant&&) moving speed on different types II"); for (std::size_t i = 0; i < c_run_count; ++i) { data_to[i] = boost::move(data_from[i]); } if (do_count_cleanup_time) { data_to.clear(); data_from.clear(); } } std::cout << "#############################################\n"; std::vector s1(c_run_count, hello2); data_to.clear(); data_to.resize(c_run_count, var_t(0)); { scope sc("boost::variant=(const T&) copying speed"); for (std::size_t i = 0; i < c_run_count; ++i) { data_to[i] = s1[i]; } if (do_count_cleanup_time) { data_to.clear(); s1.clear(); } } std::vector s2(c_run_count, hello2); data_to.clear(); data_to.resize(c_run_count, var_t(0)); { scope sc("boost::variant=(T&&) moving speed"); for (std::size_t i = 0; i < c_run_count; ++i) { data_to[i] = boost::move(s2[i]); } if (do_count_cleanup_time) { data_to.clear(); s2.clear(); } } } int main () { #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES std::cout << "# Running tests in C++11 mode (with rvalues).\n"; #else std::cout << "# Running tests in C++03 mode (without rvalues).\n"; #endif do_test(false); do_test(true); }