]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | ////////////////////////////////////////////////////////////////////////////// |
2 | // | |
3 | // (C) Copyright Ion Gaztanaga 2007-2013. Distributed under the Boost | |
4 | // Software License, Version 1.0. (See accompanying file | |
5 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
6 | // | |
7 | // See http://www.boost.org/libs/container for documentation. | |
8 | // | |
9 | ////////////////////////////////////////////////////////////////////////////// | |
10 | ||
11 | #ifdef _MSC_VER | |
12 | #pragma warning (disable : 4512) | |
13 | #pragma warning (disable : 4267) | |
14 | #pragma warning (disable : 4244) | |
15 | #endif | |
16 | ||
17 | #define BOOST_CONTAINER_VECTOR_ALLOC_STATS | |
18 | ||
19 | #include <boost/container/allocator.hpp> | |
20 | #include <vector> | |
21 | #include <boost/container/vector.hpp> | |
22 | ||
23 | #include <memory> //std::allocator | |
24 | #include <iostream> //std::cout, std::endl | |
25 | #include <cstring> //std::strcmp | |
20effc67 | 26 | #include <boost/move/detail/nsec_clock.hpp> |
b32b8144 | 27 | #include <typeinfo> |
20effc67 TL |
28 | using boost::move_detail::cpu_timer; |
29 | using boost::move_detail::cpu_times; | |
30 | using boost::move_detail::nanosecond_type; | |
7c673cae FG |
31 | |
32 | namespace bc = boost::container; | |
33 | ||
7c673cae | 34 | #if defined(BOOST_CONTAINER_VECTOR_ALLOC_STATS) |
7c673cae | 35 | |
b32b8144 FG |
36 | template<class T, class Allocator> |
37 | static void reset_alloc_stats(std::vector<T, Allocator> &) | |
38 | {} | |
7c673cae | 39 | |
b32b8144 FG |
40 | template<class T, class Allocator> |
41 | static std::size_t get_num_alloc(std::vector<T, Allocator> &) | |
42 | { return 0; } | |
7c673cae | 43 | |
b32b8144 FG |
44 | template<class T, class Allocator> |
45 | static std::size_t get_num_expand(std::vector<T, Allocator> &) | |
46 | { return 0; } | |
7c673cae | 47 | |
b32b8144 FG |
48 | template<class T, class Allocator> |
49 | static void reset_alloc_stats(bc::vector<T, Allocator> &v) | |
50 | { v.reset_alloc_stats(); } | |
7c673cae | 51 | |
b32b8144 FG |
52 | template<class T, class Allocator> |
53 | static std::size_t get_num_alloc(bc::vector<T, Allocator> &v) | |
54 | { return v.num_alloc; } | |
7c673cae | 55 | |
b32b8144 FG |
56 | template<class T, class Allocator> |
57 | static std::size_t get_num_expand(bc::vector<T, Allocator> &v) | |
58 | { return v.num_expand_fwd; } | |
7c673cae FG |
59 | |
60 | #endif //BOOST_CONTAINER_VECTOR_ALLOC_STATS | |
61 | ||
7c673cae FG |
62 | class MyInt |
63 | { | |
64 | int int_; | |
65 | ||
66 | public: | |
67 | explicit MyInt(int i = 0) | |
68 | : int_(i) | |
69 | {} | |
70 | ||
71 | MyInt(const MyInt &other) | |
72 | : int_(other.int_) | |
73 | {} | |
74 | ||
75 | MyInt & operator=(const MyInt &other) | |
76 | { | |
77 | int_ = other.int_; | |
78 | return *this; | |
79 | } | |
80 | ||
81 | ~MyInt() | |
82 | { | |
83 | int_ = 0; | |
84 | } | |
85 | }; | |
86 | ||
b32b8144 | 87 | template<class Container> |
1e59de90 | 88 | void vector_test_template(std::size_t num_iterations, std::size_t num_elements) |
7c673cae | 89 | { |
1e59de90 | 90 | std::size_t numalloc = 0, numexpand = 0; |
7c673cae | 91 | |
7c673cae FG |
92 | cpu_timer timer; |
93 | timer.resume(); | |
94 | ||
1e59de90 TL |
95 | std::size_t capacity = 0; |
96 | for(std::size_t r = 0; r != num_iterations; ++r){ | |
b32b8144 | 97 | Container v; |
7c673cae | 98 | #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS |
b32b8144 | 99 | reset_alloc_stats(v); |
7c673cae FG |
100 | #endif |
101 | //v.reserve(num_elements); | |
102 | //MyInt a[3]; | |
103 | /* | |
1e59de90 | 104 | for(std::size_t e = 0; e != num_elements/3; ++e){ |
7c673cae FG |
105 | v.insert(v.end(), &a[0], &a[0]+3); |
106 | }*/ | |
107 | /* | |
1e59de90 TL |
108 | for(std::size_t e = 0; e != num_elements/3; ++e){ |
109 | v.insert(v.end(), 3, MyInt((int)e)); | |
7c673cae FG |
110 | }*/ |
111 | /* | |
1e59de90 | 112 | for(std::size_t e = 0; e != num_elements/3; ++e){ |
7c673cae FG |
113 | v.insert(v.empty() ? v.end() : --v.end(), &a[0], &a[0]+3); |
114 | }*/ | |
115 | /* | |
1e59de90 TL |
116 | for(std::size_t e = 0; e != num_elements/3; ++e){ |
117 | v.insert(v.empty() ? v.end() : --v.end(), 3, MyInt((int)e)); | |
7c673cae FG |
118 | }*/ |
119 | /* | |
1e59de90 | 120 | for(std::size_t e = 0; e != num_elements/3; ++e){ |
7c673cae FG |
121 | v.insert(v.size() >= 3 ? v.end()-3 : v.begin(), &a[0], &a[0]+3); |
122 | }*/ | |
123 | /* | |
1e59de90 TL |
124 | for(std::size_t e = 0; e != num_elements/3; ++e){ |
125 | v.insert(v.size() >= 3 ? v.end()-3 : v.begin(), 3, MyInt((int)e)); | |
7c673cae FG |
126 | }*/ |
127 | /* | |
1e59de90 TL |
128 | for(std::size_t e = 0; e != num_elements; ++e){ |
129 | v.insert(v.end(), MyInt((int)e)); | |
7c673cae FG |
130 | }*/ |
131 | /* | |
1e59de90 TL |
132 | for(std::size_t e = 0; e != num_elements; ++e){ |
133 | v.insert(v.empty() ? v.end() : --v.end(), MyInt((int)e)); | |
7c673cae FG |
134 | }*/ |
135 | ||
1e59de90 TL |
136 | for(std::size_t e = 0; e != num_elements; ++e){ |
137 | v.push_back(MyInt((int)e)); | |
7c673cae FG |
138 | } |
139 | ||
140 | #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS | |
b32b8144 FG |
141 | numalloc += get_num_alloc(v); |
142 | numexpand += get_num_expand(v); | |
7c673cae | 143 | #endif |
1e59de90 | 144 | capacity = static_cast<std::size_t>(v.capacity()); |
7c673cae FG |
145 | } |
146 | ||
147 | timer.stop(); | |
148 | nanosecond_type nseconds = timer.elapsed().wall; | |
149 | ||
b32b8144 FG |
150 | std::cout << std::endl |
151 | << "Allocator: " << typeid(typename Container::allocator_type).name() | |
152 | << std::endl | |
153 | << " push_back ns: " | |
1e59de90 | 154 | << float(nseconds)/float(num_iterations*num_elements) |
b32b8144 FG |
155 | << std::endl |
156 | << " capacity - alloc calls (new/expand): " | |
1e59de90 TL |
157 | << (std::size_t)capacity << " - " |
158 | << (float(numalloc) + float(numexpand))/float(num_iterations) | |
159 | << "(" << float(numalloc)/float(num_iterations) << "/" << float(numexpand)/float(num_iterations) << ")" | |
b32b8144 | 160 | << std::endl << std::endl; |
7c673cae FG |
161 | bc::dlmalloc_trim(0); |
162 | } | |
163 | ||
164 | void print_header() | |
165 | { | |
166 | std::cout << "Allocator" << ";" << "Iterations" << ";" << "Size" << ";" | |
167 | << "Capacity" << ";" << "push_back(ns)" << ";" << "Allocator calls" << ";" | |
168 | << "New allocations" << ";" << "Fwd expansions" << std::endl; | |
169 | } | |
170 | ||
b32b8144 | 171 | int main() |
7c673cae | 172 | { |
92f5a8d4 TL |
173 | //#define SINGLE_TEST |
174 | #define SIMPLE_IT | |
175 | #ifdef SINGLE_TEST | |
7c673cae | 176 | #ifdef NDEBUG |
92f5a8d4 | 177 | std::size_t numit [] = { 1000 }; |
7c673cae | 178 | #else |
92f5a8d4 | 179 | std::size_t numit [] = { 100 }; |
7c673cae | 180 | #endif |
92f5a8d4 TL |
181 | std::size_t numele [] = { 10000 }; |
182 | #elif defined SIMPLE_IT | |
183 | std::size_t numit [] = { 3 }; | |
184 | std::size_t numele [] = { 10000 }; | |
7c673cae FG |
185 | #else |
186 | #ifdef NDEBUG | |
1e59de90 | 187 | std::size_t numit [] = { 1000, 10000, 100000, 1000000 }; |
7c673cae | 188 | #else |
1e59de90 | 189 | std::size_t numit [] = { 100, 1000, 10000, 100000 }; |
7c673cae | 190 | #endif |
1e59de90 | 191 | std::size_t numele [] = { 10000, 1000, 100, 10 }; |
7c673cae FG |
192 | #endif |
193 | ||
b32b8144 | 194 | print_header(); |
1e59de90 | 195 | for(std::size_t i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){ |
b32b8144 FG |
196 | vector_test_template< bc::vector<MyInt, std::allocator<MyInt> > >(numit[i], numele[i]); |
197 | vector_test_template< bc::vector<MyInt, bc::allocator<MyInt, 1> > >(numit[i], numele[i]); | |
198 | vector_test_template<bc::vector<MyInt, bc::allocator<MyInt, 2, bc::expand_bwd | bc::expand_fwd> > >(numit[i], numele[i]); | |
199 | vector_test_template<bc::vector<MyInt, bc::allocator<MyInt, 2> > >(numit[i], numele[i]); | |
7c673cae FG |
200 | } |
201 | return 0; | |
202 | } |