1 /*=============================================================================
2 Copyright (c) 2010 Tim Blechmann
4 Use, modification and distribution is subject to the Boost Software
5 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 http://www.boost.org/LICENSE_1_0.txt)
7 =============================================================================*/
12 #include <boost/foreach.hpp>
13 #include "high_resolution_timer.hpp"
15 #include <boost/heap/heap_merge.hpp>
17 #if defined(__GNUC__) && (!defined __INTEL_COMPILER)
18 #define no_inline __attribute__ ((noinline))
23 typedef std::vector<int> test_data;
25 const int num_benchmarks = 1;
27 inline test_data make_sequential_test_data(int size)
30 for (int i = 0; i != size; ++i)
35 inline test_data make_test_data(int size)
37 test_data v = make_sequential_test_data(size);
38 std::random_shuffle(v.begin(), v.end());
42 const int max_data = 20;
44 test_data const & get_data(int index)
46 static std::vector <test_data> data;
48 for (int i = 0; i != num_benchmarks; ++i)
49 data.push_back(make_test_data((1<<(max_data+1))+1024));
55 #define DEFINE_BENCHMARKS_SELECTOR(SUFFIX) \
56 struct make_##SUFFIX \
58 template <typename heap> \
60 typedef run_##SUFFIX<heap> type; \
65 template <typename pri_queue>
66 void fill_heap(pri_queue & q, int index, int size, int offset = 0)
68 test_data const & data = get_data(index);
70 for (int i = 0; i != size + 1; ++i) {
78 template <typename pri_queue,
79 typename handle_container
81 void fill_heap_with_handles(pri_queue & q, handle_container & handles, int index, int size, int offset = 0)
83 test_data const & data = get_data(index);
85 for (int i = 0; i != size + 1; ++i) {
86 handles[i] = q.push(data[i]);
89 typename pri_queue::handle_type last = handles[i-1];
92 handles[i-1] = q.push(val);
98 template <typename pri_queue>
99 struct run_sequential_push
101 run_sequential_push(int size):
105 void prepare(int index)
108 fill_heap(q, index, size);
111 no_inline void operator()(int index)
113 test_data const & data = get_data(index);
115 for (int i = 0; i != 16; ++i)
116 q.push(data[(1<<max_data) + i]);
123 DEFINE_BENCHMARKS_SELECTOR(sequential_push)
125 template <typename pri_queue>
126 struct run_sequential_pop
128 run_sequential_pop(int size):
132 void prepare(int index)
135 fill_heap(q, index, size);
138 no_inline void operator()(int index)
140 for (int i = 0; i != 16; ++i)
148 DEFINE_BENCHMARKS_SELECTOR(sequential_pop)
150 template <typename pri_queue>
151 struct run_sequential_increase
153 run_sequential_increase(int size):
154 size(size), handles(size)
157 void prepare(int index)
160 fill_heap_with_handles(q, handles, index, size);
163 no_inline void operator()(int index)
165 test_data const & data = get_data(index);
166 for (int i = 0; i != 16; ++i)
167 q.increase(handles[i], data[i] + (1<<max_data));
172 std::vector<typename pri_queue::handle_type> handles;
175 DEFINE_BENCHMARKS_SELECTOR(sequential_increase)
177 template <typename pri_queue>
178 struct run_sequential_decrease
180 run_sequential_decrease(int size):
181 size(size), handles(size)
184 void prepare(int index)
187 fill_heap_with_handles(q, handles, index, size);
190 no_inline void operator()(int index)
192 test_data const & data = get_data(index);
193 for (int i = 0; i != 16; ++i)
194 q.decrease(handles[i], data[i] + (1<<max_data));
199 std::vector<typename pri_queue::handle_type> handles;
202 DEFINE_BENCHMARKS_SELECTOR(sequential_decrease)
204 template <typename pri_queue>
205 struct run_merge_and_clear
207 run_merge_and_clear(int size):
211 void prepare(int index)
216 fill_heap(q, index, size);
217 fill_heap(r, index, size, size);
220 no_inline void operator()(int index)
222 boost::heap::heap_merge(q, r);
229 DEFINE_BENCHMARKS_SELECTOR(merge_and_clear)
231 template <typename pri_queue>
232 struct run_equivalence
234 run_equivalence(int size):
238 void prepare(int index)
244 fill_heap(q, index, size);
245 fill_heap(r, index, size, size);
246 fill_heap(s, index, size);
249 no_inline bool operator()(int index)
251 return (q == r) ^ (q == s);
258 DEFINE_BENCHMARKS_SELECTOR(equivalence)
261 template <typename benchmark>
262 inline double run_benchmark(benchmark & b)
264 boost::high_resolution_timer timer;
265 std::vector<double> results;
267 for (int i = 0; i != num_benchmarks; ++i)
272 double t = timer.elapsed();
273 results.push_back(t);
276 return results.at(results.size()/2); // median