1 // benchmark based on: http://cpp-next.com/archive/2010/10/howards-stl-move-semantics-benchmark/
2 //
3 //  @file   bench_static_vector.cpp
4 //  @date   Aug 14, 2011
5 //  @author Andrew Hundt <[email protected]>
6 //
7 //  (C) Copyright 2011-2013 Andrew Hundt <[email protected]>
8 //  (C) Copyright 2013-2013 Ion Gaztanaga
9 //
10 //  Distributed under the Boost Software License, Version 1.0. (See
11 //  accompanying file LICENSE_1_0.txt or copy at
12 //  http://www.boost.org/LICENSE_1_0.txt)
13 //
14 //  @brief  varray_benchmark.cpp compares the performance of boost::container::varray to boost::container::vector
15 
16 #include "varray.hpp"
17 #include <boost/container/vector.hpp>
18 #include <boost/container/static_vector.hpp>
19 #include <boost/core/no_exceptions_support.hpp>
20 
21 #include "../test/movable_int.hpp"
22 #include <vector>
23 #include <iostream>
24 #include <boost/move/detail/nsec_clock.hpp>
25 #include <algorithm>
26 #include <exception>
27 #include <iomanip>
28 
29 using boost::move_detail::cpu_timer;
30 using boost::move_detail::cpu_times;
31 using boost::move_detail::nanosecond_type;
32 
33 static const std::size_t N = 500;
34 
35 #ifdef NDEBUG
36 static const std::size_t Iter = 50;
37 #else
38 static const std::size_t Iter = 5;
39 #endif
40 
41 //#define BENCH_SIMPLE_CONSTRUCTION
42 //#define BENCH_TRIVIAL_TYPE
43 
44 #ifdef BENCH_TRIVIAL_TYPE
45 typedef std::size_t basic_type_t;
46 #else
47 typedef boost::container::test::copyable_int basic_type_t;
48 #endif
49 
50 template<typename T>
get_set(std::size_t)51 T &get_set(std::size_t)
52 {
53    #ifdef BENCH_SIMPLE_CONSTRUCTION
54    T &t = *new T(N);
55    for (std::size_t i = 0; i < N; ++i)
56       t[i] = basic_type_t(std::rand());
57    #else
58    T &t = *new T;
59    t.reserve(N);
60    for (std::size_t i = 0; i < N; ++i)
61       t.push_back(basic_type_t(std::rand()));
62    #endif
63    return t;
64 }
65 
66 template<typename T>
generate()67 T &generate()
68 {
69    T &v = *new T;
70    v.reserve(N);
71 
72    for (std::size_t i = 0; i < N; ++i){
73       typename T::reference r = get_set<typename T::value_type>(i);
74       v.push_back(boost::move(r));
75       delete &r;
76    }
77    return v;
78 }
79 
80 template<typename T>
time_it()81 cpu_times time_it()
82 {
83    cpu_timer sortTime,rotateTime,destructionTime;
84    sortTime.stop();rotateTime.stop();destructionTime.stop();
85    cpu_timer totalTime, constructTime;
86    std::srand (0);
87    for(std::size_t i = 0; i< Iter; ++i){
88      constructTime.resume();
89      {
90       T &v = generate<T>();
91       constructTime.stop();
92       sortTime.resume();
93       std::sort(v.begin(), v.end());
94       sortTime.stop();
95       rotateTime.resume();
96       std::rotate(v.begin(), v.begin() + v.size()/2, v.end());
97       rotateTime.stop();
98       destructionTime.resume();
99       delete &v;
100      }
101      destructionTime.stop();
102    }
103    totalTime.stop();
104    std::cout << std::fixed << std::setw( 11 );
105    std::cout << "  construction took " << double(constructTime.elapsed().wall)/double(1000000000) << "s\n";
106    std::cout << "  sort took         " << double(sortTime.elapsed().wall)/double(1000000000) << "s\n";
107    std::cout << "  rotate took       " << double(rotateTime.elapsed().wall)/double(1000000000) << "s\n";
108    std::cout << "  destruction took  " << double(destructionTime.elapsed().wall)/double(1000000000) << "s\n";
109    std::cout << "  Total time =      " << double(totalTime.elapsed().wall)/double(1000000000) << "s\n";
110    return totalTime.elapsed();
111 }
112 
compare_times(cpu_times time_numerator,cpu_times time_denominator)113 void compare_times(cpu_times time_numerator, cpu_times time_denominator){
114    std::cout
115    << "\n  wall       = " << ((double)time_numerator.wall/(double)time_denominator.wall) << "\n\n";
116 }
117 
main()118 int main()
119 {
120    std::cout << "N = " << N << " Iter = " << Iter << "\n\n";
121 
122    std::cout << "varray benchmark:" << std::endl;
123    cpu_times time_varray = time_it<boost::container::varray<boost::container::varray<basic_type_t,N>,N > >();
124 
125    std::cout << "boost::container::static_vector benchmark" << std::endl;
126    cpu_times time_boost_static_vector = time_it<boost::container::static_vector<boost::container::static_vector<basic_type_t,N>,N > >();
127 
128    std::cout << "boost::container::vector benchmark"  << std::endl;
129    cpu_times time_boost_vector = time_it<boost::container::vector<boost::container::vector<basic_type_t> > >();
130 
131    std::cout << "std::vector benchmark" << std::endl;
132    cpu_times time_standard_vector = time_it<std::vector<std::vector<basic_type_t> > >();
133 
134    std::cout << "varray/boost::container::vector total time comparison:";
135    compare_times(time_varray, time_boost_vector);
136 
137    std::cout << "varray/boost::container::static_vector total time comparison:";
138    compare_times(time_varray, time_boost_static_vector);
139 
140    std::cout << "varray/std::vector total time comparison:";
141    compare_times(time_varray,time_standard_vector);
142 
143    return 0;
144 }
145