1 //////////////////////////////////////////////////////////////////////////////
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)
7 // See http://www.boost.org/libs/container for documentation.
9 //////////////////////////////////////////////////////////////////////////////
13 #include <boost/container/vector.hpp>
14 #include <boost/container/devector.hpp>
15 #include <boost/container/deque.hpp>
16 #include <boost/container/small_vector.hpp>
17 #include <boost/container/stable_vector.hpp>
19 #include <memory> //std::allocator
20 #include <iostream> //std::cout, std::endl
21 #include <cstring> //std::strcmp
22 #include <boost/move/detail/nsec_clock.hpp>
26 #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME capacity
27 #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace test {
28 #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
29 #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 0
30 #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0
31 #include <boost/intrusive/detail/has_member_function_callable_with.hpp>
33 using boost::move_detail::cpu_timer
;
34 using boost::move_detail::cpu_times
;
35 using boost::move_detail::nanosecond_type
;
37 namespace bc
= boost::container
;
44 BOOST_CONTAINER_FORCEINLINE
explicit MyInt(int i
= 0)
48 BOOST_CONTAINER_FORCEINLINE
MyInt(const MyInt
&other
)
52 BOOST_CONTAINER_FORCEINLINE MyInt
& operator=(const MyInt
&other
)
58 BOOST_CONTAINER_FORCEINLINE
~MyInt()
64 template<class C
, bool = boost::container::test::
65 has_member_function_callable_with_capacity
<C
>::value
>
66 struct capacity_wrapper
68 BOOST_CONTAINER_FORCEINLINE
static typename
C::size_type
get_capacity(const C
&c
)
69 { return c
.capacity(); }
71 BOOST_CONTAINER_FORCEINLINE
static void set_reserve(C
&c
, typename
C::size_type cp
)
76 struct capacity_wrapper
<C
, false>
78 BOOST_CONTAINER_FORCEINLINE
static typename
C::size_type
get_capacity(const C
&)
81 BOOST_CONTAINER_FORCEINLINE
static void set_reserve(C
&, typename
C::size_type
)
85 const std::size_t RangeSize
= 5;
87 struct insert_end_range
89 BOOST_CONTAINER_FORCEINLINE
std::size_t capacity_multiplier() const
93 BOOST_CONTAINER_FORCEINLINE
void operator()(C
&c
, int)
94 { c
.insert(c
.end(), &a
[0], &a
[0]+RangeSize
); }
96 const char *name() const
97 { return "insert_end_range"; }
102 struct insert_end_repeated
104 BOOST_CONTAINER_FORCEINLINE
std::size_t capacity_multiplier() const
105 { return RangeSize
; }
108 BOOST_CONTAINER_FORCEINLINE
void operator()(C
&c
, int i
)
109 { c
.insert(c
.end(), RangeSize
, MyInt(i
)); }
111 BOOST_CONTAINER_FORCEINLINE
const char *name() const
112 { return "insert_end_repeated"; }
119 BOOST_CONTAINER_FORCEINLINE
std::size_t capacity_multiplier() const
123 BOOST_CONTAINER_FORCEINLINE
void operator()(C
&c
, int i
)
124 { c
.push_back(MyInt(i
)); }
126 BOOST_CONTAINER_FORCEINLINE
const char *name() const
127 { return "push_back"; }
130 struct insert_near_end_repeated
132 BOOST_CONTAINER_FORCEINLINE
std::size_t capacity_multiplier() const
133 { return RangeSize
; }
136 BOOST_CONTAINER_FORCEINLINE
void operator()(C
&c
, int i
)
137 { c
.insert(c
.size() >= 2*RangeSize
? c
.end()-2*RangeSize
: c
.begin(), RangeSize
, MyInt(i
)); }
139 BOOST_CONTAINER_FORCEINLINE
const char *name() const
140 { return "insert_near_end_repeated"; }
143 struct insert_near_end_range
145 BOOST_CONTAINER_FORCEINLINE
std::size_t capacity_multiplier() const
146 { return RangeSize
; }
149 BOOST_CONTAINER_FORCEINLINE
void operator()(C
&c
, int)
151 c
.insert(c
.size() >= 2*RangeSize
? c
.end()-2*RangeSize
: c
.begin(), &a
[0], &a
[0]+RangeSize
);
154 BOOST_CONTAINER_FORCEINLINE
const char *name() const
155 { return "insert_near_end_range"; }
160 struct insert_near_end
162 BOOST_CONTAINER_FORCEINLINE
std::size_t capacity_multiplier() const
166 BOOST_CONTAINER_FORCEINLINE
void operator()(C
&c
, int i
)
168 typedef typename
C::iterator it_t
;
170 it
-= static_cast<typename
C::size_type
>(c
.size() >= 2)*2;
171 c
.insert(it
, MyInt(i
));
174 BOOST_CONTAINER_FORCEINLINE
const char *name() const
175 { return "insert_near_end"; }
179 template<class Container
, class Operation
>
180 void vector_test_template(std::size_t num_iterations
, std::size_t num_elements
, const char *cont_name
)
182 typedef capacity_wrapper
<Container
> cpw_t
;
185 cpw_t::set_reserve(c
, num_elements
);
188 const typename
Container::size_type multiplier
= op
.capacity_multiplier();
191 for(std::size_t e
= 0, max
= num_elements
/multiplier
; e
!= max
; ++e
){
192 op(c
, static_cast<int>(e
));
198 const std::size_t max
= num_elements
/multiplier
;
199 for(std::size_t r
= 0; r
!= num_iterations
; ++r
){
201 //Unrolll the loop to avoid noise from loop code
204 for(std::size_t e
= 0; e
< max
/16; ++e
){
205 op(c
, static_cast<int>(i
++));
206 op(c
, static_cast<int>(i
++));
207 op(c
, static_cast<int>(i
++));
208 op(c
, static_cast<int>(i
++));
209 op(c
, static_cast<int>(i
++));
210 op(c
, static_cast<int>(i
++));
211 op(c
, static_cast<int>(i
++));
212 op(c
, static_cast<int>(i
++));
213 op(c
, static_cast<int>(i
++));
214 op(c
, static_cast<int>(i
++));
215 op(c
, static_cast<int>(i
++));
216 op(c
, static_cast<int>(i
++));
217 op(c
, static_cast<int>(i
++));
218 op(c
, static_cast<int>(i
++));
219 op(c
, static_cast<int>(i
++));
220 op(c
, static_cast<int>(i
++));
229 std::size_t capacity
= cpw_t::get_capacity(c
);
231 nanosecond_type nseconds
= timer
.elapsed().wall
;
233 std::cout
<< cont_name
<< "->" << op
.name() <<" ns: "
234 << float(nseconds
)/(num_iterations
*num_elements
)
236 << "Capacity: " << capacity
240 template<class Operation
>
243 //#define SINGLE_TEST
247 std::size_t numit
[] = { 100 };
249 std::size_t numit
[] = { 20 };
251 std::size_t numele
[] = { 10000 };
252 #elif defined SIMPLE_IT
253 std::size_t numit
[] = { 100 };
254 std::size_t numele
[] = { 10000 };
257 unsigned int numit
[] = { 1000, 10000, 100000, 1000000 };
259 unsigned int numit
[] = { 100, 1000, 10000, 100000 };
261 unsigned int numele
[] = { 10000, 1000, 100, 10 };
264 for(unsigned int i
= 0; i
< sizeof(numele
)/sizeof(numele
[0]); ++i
){
265 vector_test_template
< std::vector
<MyInt
, std::allocator
<MyInt
> >, Operation
>(numit
[i
], numele
[i
] , "std::vector ");
266 vector_test_template
< bc::vector
<MyInt
, std::allocator
<MyInt
> >, Operation
>(numit
[i
], numele
[i
] , "vector ");
267 vector_test_template
< bc::devector
<MyInt
, std::allocator
<MyInt
> >, Operation
>(numit
[i
], numele
[i
] , "devector ");
268 vector_test_template
< bc::small_vector
<MyInt
, 0, std::allocator
<MyInt
> >, Operation
>(numit
[i
], numele
[i
] , "small_vector ");
269 vector_test_template
< std::deque
<MyInt
, std::allocator
<MyInt
> >, Operation
>(numit
[i
], numele
[i
] , "std::deque ");
270 vector_test_template
< bc::deque
<MyInt
, std::allocator
<MyInt
> >, Operation
>(numit
[i
], numele
[i
] , "deque ");
273 std::cout
<< "---------------------------------\n---------------------------------\n";
279 test_vectors
<push_back
>();
280 test_vectors
<insert_end_range
>();
281 test_vectors
<insert_end_repeated
>();
283 test_vectors
<insert_near_end
>();
284 test_vectors
<insert_near_end_range
>();
285 test_vectors
<insert_near_end_repeated
>();