blob: efdd31d0077bfc417d4bb3d6ea4ba8a20f0bc0bf [file] [log] [blame]
// (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 <boost/chrono.hpp>
#include <boost/variant.hpp>
#include <string>
#include <vector>
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<duration_t>(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<char> str_t;
typedef boost::variant<int, str_t, float> 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<var_t> 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<str_t> 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<str_t> 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);
}