]>
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 | #endif | |
14 | ||
15 | #include <boost/container/allocator.hpp> | |
16 | ||
17 | #define BOOST_CONTAINER_VECTOR_ALLOC_STATS | |
18 | ||
19 | #include <boost/container/vector.hpp> | |
20 | ||
21 | #undef BOOST_CONTAINER_VECTOR_ALLOC_STATS | |
22 | ||
23 | #include <memory> //std::allocator | |
24 | #include <iostream> //std::cout, std::endl | |
25 | #include <cassert> //assert | |
26 | ||
27 | #include <boost/timer/timer.hpp> | |
28 | using boost::timer::cpu_timer; | |
29 | using boost::timer::cpu_times; | |
30 | using boost::timer::nanosecond_type; | |
31 | ||
32 | namespace bc = boost::container; | |
33 | ||
34 | typedef std::allocator<int> StdAllocator; | |
35 | typedef bc::allocator<int, 2> AllocatorPlusV2; | |
36 | typedef bc::allocator<int, 1> AllocatorPlusV1; | |
37 | ||
38 | template<class Allocator> struct get_allocator_name; | |
39 | ||
40 | template<> struct get_allocator_name<StdAllocator> | |
41 | { static const char *get() { return "StdAllocator"; } }; | |
42 | ||
43 | template<> struct get_allocator_name<AllocatorPlusV2> | |
44 | { static const char *get() { return "AllocatorPlusV2"; } }; | |
45 | ||
46 | template<> struct get_allocator_name<AllocatorPlusV1> | |
47 | { static const char *get() { return "AllocatorPlusV1"; } }; | |
48 | ||
49 | class MyInt | |
50 | { | |
51 | std::size_t int_; //Use a type that will grow on 64 bit machines | |
52 | ||
53 | public: | |
54 | MyInt(int i = 0) : int_(i){} | |
55 | ||
56 | MyInt(const MyInt &other) | |
57 | : int_(other.int_) | |
58 | {} | |
59 | ||
60 | MyInt & operator=(const MyInt &other) | |
61 | { | |
62 | int_ = other.int_; | |
63 | return *this; | |
64 | } | |
65 | }; | |
66 | ||
67 | void print_header() | |
68 | { | |
69 | std::cout << "Allocator" << ";" << "Iterations" << ";" << "Size" << ";" | |
70 | << "num_shrink" << ";" << "shrink_to_fit(ns)" << std::endl; | |
71 | } | |
72 | ||
73 | template<class Allocator> | |
74 | void vector_test_template(unsigned int num_iterations, unsigned int num_elements, bool csv_output) | |
75 | { | |
76 | typedef typename Allocator::template rebind<MyInt>::other IntAllocator; | |
77 | ||
78 | unsigned int capacity = 0; | |
79 | const std::size_t Step = 5; | |
80 | unsigned int num_shrink = 0; | |
81 | (void)capacity; | |
82 | ||
83 | cpu_timer timer; | |
84 | timer.resume(); | |
85 | ||
86 | #ifndef NDEBUG | |
11fdf7f2 TL |
87 | typedef bc::dtl::integral_constant |
88 | <unsigned, bc::dtl::version<Allocator>::value> alloc_version; | |
7c673cae FG |
89 | #endif |
90 | ||
91 | for(unsigned int r = 0; r != num_iterations; ++r){ | |
92 | bc::vector<MyInt, IntAllocator> v(num_elements); | |
93 | v.reset_alloc_stats(); | |
94 | num_shrink = 0; | |
95 | for(unsigned int e = num_elements; e != 0; e -= Step){ | |
96 | v.erase(v.end() - Step, v.end()); | |
97 | v.shrink_to_fit(); | |
98 | assert( (alloc_version::value != 2) || (e == Step) || (v.num_shrink > num_shrink) ); | |
99 | num_shrink = v.num_shrink; | |
100 | } | |
101 | assert(v.empty()); | |
102 | assert(0 == v.capacity()); | |
103 | } | |
104 | ||
105 | timer.stop(); | |
106 | nanosecond_type nseconds = timer.elapsed().wall; | |
107 | ||
108 | if(csv_output){ | |
109 | std::cout << get_allocator_name<Allocator>::get() | |
110 | << ";" | |
111 | << num_iterations | |
112 | << ";" | |
113 | << num_elements | |
114 | << ";" | |
115 | << num_shrink | |
116 | << ";" | |
117 | << float(nseconds)/(num_iterations*num_elements) | |
118 | << std::endl; | |
119 | } | |
120 | else{ | |
121 | std::cout << std::endl | |
122 | << "Allocator: " << get_allocator_name<Allocator>::get() | |
123 | << std::endl | |
124 | << " num_shrink: " << num_shrink | |
125 | << std::endl | |
126 | << " shrink_to_fit ns: " | |
127 | << float(nseconds)/(num_iterations*num_elements) | |
128 | << std::endl << std::endl; | |
129 | } | |
130 | bc::dlmalloc_trim(0); | |
131 | } | |
132 | ||
133 | int main(int argc, const char *argv[]) | |
134 | { | |
135 | #define SINGLE_TEST | |
136 | #ifndef SINGLE_TEST | |
137 | #ifdef NDEBUG | |
138 | unsigned int numit [] = { 100, 1000, 10000 }; | |
139 | #else | |
140 | unsigned int numit [] = { 10, 100, 1000 }; | |
141 | #endif | |
142 | unsigned int numele [] = { 10000, 2000, 500 }; | |
143 | #else | |
144 | #ifdef NDEBUG | |
145 | unsigned int numit [] = { 500 }; | |
146 | #else | |
147 | unsigned int numit [] = { 50 }; | |
148 | #endif | |
149 | unsigned int numele [] = { 2000 }; | |
150 | #endif | |
151 | ||
152 | bool csv_output = argc == 2 && (strcmp(argv[1], "--csv-output") == 0); | |
153 | ||
154 | if(csv_output){ | |
155 | print_header(); | |
156 | for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){ | |
157 | vector_test_template<StdAllocator>(numit[i], numele[i], csv_output); | |
158 | } | |
159 | for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){ | |
160 | vector_test_template<AllocatorPlusV1>(numit[i], numele[i], csv_output); | |
161 | } | |
162 | for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){ | |
163 | vector_test_template<AllocatorPlusV2>(numit[i], numele[i], csv_output); | |
164 | } | |
165 | } | |
166 | else{ | |
167 | for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){ | |
168 | std::cout << "\n ----------------------------------- \n" | |
169 | << " Iterations/Elements: " << numit[i] << "/" << numele[i] | |
170 | << "\n ----------------------------------- \n"; | |
171 | vector_test_template<StdAllocator>(numit[i], numele[i], csv_output); | |
172 | vector_test_template<AllocatorPlusV1>(numit[i], numele[i], csv_output); | |
173 | vector_test_template<AllocatorPlusV2>(numit[i], numele[i], csv_output); | |
174 | } | |
175 | } | |
176 | return 0; | |
177 | } |