Squashed 'third_party/boostorg/container/' content from commit 1ad6431
Change-Id: I7d095db3455264c03446268e5675b926bebedb0a
git-subtree-dir: third_party/boostorg/container
git-subtree-split: 1ad64316a432a7f021b4956acf88abc6aaa8a77e
diff --git a/bench/bench_alloc_shrink_to_fit.cpp b/bench/bench_alloc_shrink_to_fit.cpp
new file mode 100644
index 0000000..687d76d
--- /dev/null
+++ b/bench/bench_alloc_shrink_to_fit.cpp
@@ -0,0 +1,177 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2013. Distributed under 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifdef _MSC_VER
+#pragma warning (disable : 4512)
+#endif
+
+#include <boost/container/allocator.hpp>
+
+#define BOOST_CONTAINER_VECTOR_ALLOC_STATS
+
+#include <boost/container/vector.hpp>
+
+#undef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+
+#include <memory> //std::allocator
+#include <iostream> //std::cout, std::endl
+#include <cassert> //assert
+
+#include <boost/timer/timer.hpp>
+using boost::timer::cpu_timer;
+using boost::timer::cpu_times;
+using boost::timer::nanosecond_type;
+
+namespace bc = boost::container;
+
+typedef std::allocator<int> StdAllocator;
+typedef bc::allocator<int, 2> AllocatorPlusV2;
+typedef bc::allocator<int, 1> AllocatorPlusV1;
+
+template<class Allocator> struct get_allocator_name;
+
+template<> struct get_allocator_name<StdAllocator>
+{ static const char *get() { return "StdAllocator"; } };
+
+template<> struct get_allocator_name<AllocatorPlusV2>
+{ static const char *get() { return "AllocatorPlusV2"; } };
+
+template<> struct get_allocator_name<AllocatorPlusV1>
+{ static const char *get() { return "AllocatorPlusV1"; } };
+
+class MyInt
+{
+ std::size_t int_; //Use a type that will grow on 64 bit machines
+
+ public:
+ MyInt(int i = 0) : int_(i){}
+
+ MyInt(const MyInt &other)
+ : int_(other.int_)
+ {}
+
+ MyInt & operator=(const MyInt &other)
+ {
+ int_ = other.int_;
+ return *this;
+ }
+};
+
+void print_header()
+{
+ std::cout << "Allocator" << ";" << "Iterations" << ";" << "Size" << ";"
+ << "num_shrink" << ";" << "shrink_to_fit(ns)" << std::endl;
+}
+
+template<class Allocator>
+void vector_test_template(unsigned int num_iterations, unsigned int num_elements, bool csv_output)
+{
+ typedef typename Allocator::template rebind<MyInt>::other IntAllocator;
+
+ unsigned int capacity = 0;
+ const std::size_t Step = 5;
+ unsigned int num_shrink = 0;
+ (void)capacity;
+
+ cpu_timer timer;
+ timer.resume();
+
+ #ifndef NDEBUG
+ typedef bc::dtl::integral_constant
+ <unsigned, bc::dtl::version<Allocator>::value> alloc_version;
+ #endif
+
+ for(unsigned int r = 0; r != num_iterations; ++r){
+ bc::vector<MyInt, IntAllocator> v(num_elements);
+ v.reset_alloc_stats();
+ num_shrink = 0;
+ for(unsigned int e = num_elements; e != 0; e -= Step){
+ v.erase(v.end() - Step, v.end());
+ v.shrink_to_fit();
+ assert( (alloc_version::value != 2) || (e == Step) || (v.num_shrink > num_shrink) );
+ num_shrink = v.num_shrink;
+ }
+ assert(v.empty());
+ assert(0 == v.capacity());
+ }
+
+ timer.stop();
+ nanosecond_type nseconds = timer.elapsed().wall;
+
+ if(csv_output){
+ std::cout << get_allocator_name<Allocator>::get()
+ << ";"
+ << num_iterations
+ << ";"
+ << num_elements
+ << ";"
+ << num_shrink
+ << ";"
+ << float(nseconds)/(num_iterations*num_elements)
+ << std::endl;
+ }
+ else{
+ std::cout << std::endl
+ << "Allocator: " << get_allocator_name<Allocator>::get()
+ << std::endl
+ << " num_shrink: " << num_shrink
+ << std::endl
+ << " shrink_to_fit ns: "
+ << float(nseconds)/(num_iterations*num_elements)
+ << std::endl << std::endl;
+ }
+ bc::dlmalloc_trim(0);
+}
+
+int main(int argc, const char *argv[])
+{
+ #define SINGLE_TEST
+ #ifndef SINGLE_TEST
+ #ifdef NDEBUG
+ unsigned int numit [] = { 100, 1000, 10000 };
+ #else
+ unsigned int numit [] = { 10, 100, 1000 };
+ #endif
+ unsigned int numele [] = { 10000, 2000, 500 };
+ #else
+ #ifdef NDEBUG
+ unsigned int numit [] = { 500 };
+ #else
+ unsigned int numit [] = { 50 };
+ #endif
+ unsigned int numele [] = { 2000 };
+ #endif
+
+ bool csv_output = argc == 2 && (strcmp(argv[1], "--csv-output") == 0);
+
+ if(csv_output){
+ print_header();
+ for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
+ vector_test_template<StdAllocator>(numit[i], numele[i], csv_output);
+ }
+ for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
+ vector_test_template<AllocatorPlusV1>(numit[i], numele[i], csv_output);
+ }
+ for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
+ vector_test_template<AllocatorPlusV2>(numit[i], numele[i], csv_output);
+ }
+ }
+ else{
+ for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
+ std::cout << "\n ----------------------------------- \n"
+ << " Iterations/Elements: " << numit[i] << "/" << numele[i]
+ << "\n ----------------------------------- \n";
+ vector_test_template<StdAllocator>(numit[i], numele[i], csv_output);
+ vector_test_template<AllocatorPlusV1>(numit[i], numele[i], csv_output);
+ vector_test_template<AllocatorPlusV2>(numit[i], numele[i], csv_output);
+ }
+ }
+ return 0;
+}