Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/pool/test/time_pool_alloc.cpp @ 29

Last change on this file since 29 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 13.3 KB
Line 
1// Copyright (C) 2000, 2001 Stephen Cleary
2//
3// Distributed under the Boost Software License, Version 1.0. (See
4// accompanying file LICENSE_1_0.txt or copy at
5// http://www.boost.org/LICENSE_1_0.txt)
6
7#include <boost/pool/pool_alloc.hpp>
8#include <boost/pool/object_pool.hpp>
9
10#include <iostream>
11#include <vector>
12#include <list>
13#include <set>
14
15#include <ctime>
16#include <cerrno>
17
18#include "sys_allocator.hpp"
19
20unsigned long num_ints;
21
22template <unsigned N>
23struct larger_structure
24{
25  char data[N];
26};
27
28unsigned test_number;
29
30template <unsigned N>
31static void timing_test_alloc_larger()
32{
33  typedef boost::fast_pool_allocator<larger_structure<N>,
34      boost::default_user_allocator_new_delete,
35      boost::details::pool::null_mutex> alloc;
36  typedef boost::fast_pool_allocator<larger_structure<N> > alloc_sync;
37
38  double end[1][6];
39  std::clock_t start;
40
41  start = std::clock();
42  {
43    std::allocator<larger_structure<N> > a;
44    for (unsigned long i = 0; i < num_ints; ++i)
45      a.deallocate(a.allocate(1), 1);
46  }
47  end[0][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
48
49  start = std::clock();
50  {
51    for (unsigned long i = 0; i < num_ints; ++i)
52      std::free(std::malloc(sizeof(larger_structure<N>)));
53  }
54  end[0][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
55
56  start = std::clock();
57  {
58    for (unsigned long i = 0; i < num_ints; ++i)
59      delete new (std::nothrow) larger_structure<N>;
60  }
61  end[0][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
62
63  start = std::clock();
64  {
65    for (unsigned long i = 0; i < num_ints; ++i)
66      alloc::deallocate(alloc::allocate());
67  }
68  end[0][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
69
70  start = std::clock();
71  {
72    for (unsigned long i = 0; i < num_ints; ++i)
73      alloc_sync::deallocate(alloc_sync::allocate());
74  }
75  end[0][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
76
77  start = std::clock();
78  {
79    boost::pool<> p(sizeof(larger_structure<N>));
80    for (unsigned long i = 0; i < num_ints; ++i)
81    {
82      void * const t = p.malloc();
83      if (t != 0)
84        p.free(t);
85    }
86  }
87  end[0][5] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
88
89  std::cout << "Test " << test_number++ << ": Alloc & Dealloc " << num_ints << " structures of size " << sizeof(larger_structure<N>) << ":" << std::endl;
90  std::cout << "  std::allocator: " << end[0][0] << " seconds" << std::endl;
91  std::cout << "  malloc/free:    " << end[0][1] << " seconds" << std::endl;
92  std::cout << "  new/delete:     " << end[0][2] << " seconds" << std::endl;
93  std::cout << "  Pool Alloc:     " << end[0][3] << " seconds" << std::endl;
94  std::cout << "  Pool /w Sync:   " << end[0][4] << " seconds" << std::endl;
95  std::cout << "  Pool:           " << end[0][5] << " seconds" << std::endl;
96}
97
98static void timing_test_alloc()
99{
100  typedef boost::fast_pool_allocator<int,
101      boost::default_user_allocator_new_delete,
102      boost::details::pool::null_mutex> alloc;
103  typedef boost::fast_pool_allocator<int> alloc_sync;
104
105  double end[2][6];
106  std::clock_t start;
107
108  int ** p = new int*[num_ints];
109
110  start = std::clock();
111  {
112    std::allocator<int> a;
113    for (unsigned long i = 0; i < num_ints; ++i)
114      a.deallocate(a.allocate(1), 1);
115  }
116  end[0][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
117
118  start = std::clock();
119  {
120    for (unsigned long i = 0; i < num_ints; ++i)
121      std::free(std::malloc(sizeof(int)));
122  }
123  end[0][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
124
125  start = std::clock();
126  {
127    for (unsigned long i = 0; i < num_ints; ++i)
128      delete new (std::nothrow) int;
129  }
130  end[0][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
131
132  start = std::clock();
133  {
134    for (unsigned long i = 0; i < num_ints; ++i)
135      alloc::deallocate(alloc::allocate());
136  }
137  end[0][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
138
139  start = std::clock();
140  {
141    for (unsigned long i = 0; i < num_ints; ++i)
142      alloc_sync::deallocate(alloc_sync::allocate());
143  }
144  end[0][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
145
146  start = std::clock();
147  {
148    boost::pool<> p(sizeof(int));
149    for (unsigned long i = 0; i < num_ints; ++i)
150    {
151      void * const t = p.malloc();
152      if (t != 0)
153        p.free(t);
154    }
155  }
156  end[0][5] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
157
158
159  start = std::clock();
160  {
161    std::allocator<int> a;
162    for (unsigned long i = 0; i < num_ints; ++i)
163      p[i] = a.allocate(1);
164    for (unsigned long i = 0; i < num_ints; ++i)
165      a.deallocate(p[i], 1);
166  }
167  end[1][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
168
169  start = std::clock();
170  {
171    for (unsigned long i = 0; i < num_ints; ++i)
172      p[i] = (int *) std::malloc(sizeof(int));
173    for (unsigned long i = 0; i < num_ints; ++i)
174      std::free(p[i]);
175  }
176  end[1][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
177
178  start = std::clock();
179  {
180    for (unsigned long i = 0; i < num_ints; ++i)
181      p[i] = new (std::nothrow) int;
182    for (unsigned long i = 0; i < num_ints; ++i)
183      delete p[i];
184  }
185  end[1][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
186
187  start = std::clock();
188  {
189    for (unsigned long i = 0; i < num_ints; ++i)
190      p[i] = alloc::allocate();
191    for (unsigned long i = 0; i < num_ints; ++i)
192      alloc::deallocate(p[i]);
193  }
194  end[1][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
195
196  start = std::clock();
197  {
198    for (unsigned long i = 0; i < num_ints; ++i)
199      p[i] = alloc_sync::allocate();
200    for (unsigned long i = 0; i < num_ints; ++i)
201      alloc_sync::deallocate(p[i]);
202  }
203  end[1][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
204
205  start = std::clock();
206  {
207    boost::pool<> pl(sizeof(int));
208    for (unsigned long i = 0; i < num_ints; ++i)
209      p[i] = reinterpret_cast<int *>(pl.malloc());
210    for (unsigned long i = 0; i < num_ints; ++i)
211      if (p[i] != 0)
212        pl.free(p[i]);
213  }
214  end[1][5] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
215
216  delete [] p;
217
218  std::cout << "Test 3: Alloc & Dealloc " << num_ints << " ints:" << std::endl;
219  std::cout << "  std::allocator: " << end[0][0] << " seconds" << std::endl;
220  std::cout << "  malloc/free:    " << end[0][1] << " seconds" << std::endl;
221  std::cout << "  new/delete:     " << end[0][2] << " seconds" << std::endl;
222  std::cout << "  Pool Alloc:     " << end[0][3] << " seconds" << std::endl;
223  std::cout << "  Pool /w Sync:   " << end[0][4] << " seconds" << std::endl;
224  std::cout << "  Pool:           " << end[0][5] << " seconds" << std::endl;
225
226  std::cout << "Test 4: Alloc " << num_ints << " ints & Dealloc " << num_ints << " ints:" << std::endl;
227  std::cout << "  std::allocator: " << end[1][0] << " seconds" << std::endl;
228  std::cout << "  malloc/free:    " << end[1][1] << " seconds" << std::endl;
229  std::cout << "  new/delete:     " << end[1][2] << " seconds" << std::endl;
230  std::cout << "  Pool Alloc:     " << end[1][3] << " seconds" << std::endl;
231  std::cout << "  Pool /w Sync:   " << end[1][4] << " seconds" << std::endl;
232  std::cout << "  Pool:           " << end[1][5] << " seconds" << std::endl;
233}
234
235static void timing_test_containers()
236{
237  typedef boost::pool_allocator<int,
238      boost::default_user_allocator_new_delete,
239      boost::details::pool::null_mutex> alloc;
240  typedef boost::pool_allocator<int> alloc_sync;
241  typedef boost::fast_pool_allocator<int,
242      boost::default_user_allocator_new_delete,
243      boost::details::pool::null_mutex> fast_alloc;
244  typedef boost::fast_pool_allocator<int> fast_alloc_sync;
245
246  double end[3][5];
247  std::clock_t start;
248
249  start = std::clock();
250  {
251    std::vector<int, std::allocator<int> > x;
252    for (unsigned long i = 0; i < num_ints; ++i)
253      x.push_back(0);
254  }
255  end[0][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
256
257  start = std::clock();
258  {
259    std::vector<int, malloc_allocator<int> > x;
260    for (unsigned long i = 0; i < num_ints; ++i)
261      x.push_back(0);
262  }
263  end[0][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
264
265  start = std::clock();
266  {
267    std::vector<int, new_delete_allocator<int> > x;
268    for (unsigned long i = 0; i < num_ints; ++i)
269      x.push_back(0);
270  }
271  end[0][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
272
273  start = std::clock();
274  {
275    std::vector<int, alloc> x;
276    for (unsigned long i = 0; i < num_ints; ++i)
277      x.push_back(0);
278  }
279  end[0][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
280
281  start = std::clock();
282  {
283    std::vector<int, alloc_sync> x;
284    for (unsigned long i = 0; i < num_ints; ++i)
285      x.push_back(0);
286  }
287  end[0][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
288
289
290  start = std::clock();
291  {
292    std::set<int, std::less<int>, std::allocator<int> > x;
293    for (unsigned long i = 0; i < num_ints; ++i)
294      x.insert(0);
295  }
296  end[1][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
297
298  start = std::clock();
299  {
300    std::set<int, std::less<int>, malloc_allocator<int> > x;
301    for (unsigned long i = 0; i < num_ints; ++i)
302      x.insert(0);
303  }
304  end[1][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
305
306  start = std::clock();
307  {
308    std::set<int, std::less<int>, new_delete_allocator<int> > x;
309    for (unsigned long i = 0; i < num_ints; ++i)
310      x.insert(0);
311  }
312  end[1][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
313
314  start = std::clock();
315  {
316    std::set<int, std::less<int>, fast_alloc> x;
317    for (unsigned long i = 0; i < num_ints; ++i)
318      x.insert(0);
319  }
320  end[1][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
321
322  start = std::clock();
323  {
324    std::set<int, std::less<int>, fast_alloc_sync> x;
325    for (unsigned long i = 0; i < num_ints; ++i)
326      x.insert(0);
327  }
328  end[1][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
329
330
331  start = std::clock();
332  {
333    std::list<int, std::allocator<int> > x;
334    for (unsigned long i = 0; i < num_ints; ++i)
335      x.push_back(0);
336  }
337  end[2][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
338
339  start = std::clock();
340  {
341    std::list<int, malloc_allocator<int> > x;
342    for (unsigned long i = 0; i < num_ints; ++i)
343      x.push_back(0);
344  }
345  end[2][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
346
347  start = std::clock();
348  {
349    std::list<int, new_delete_allocator<int> > x;
350    for (unsigned long i = 0; i < num_ints; ++i)
351      x.push_back(0);
352  }
353  end[2][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
354
355  start = std::clock();
356  {
357    std::list<int, fast_alloc> x;
358    for (unsigned long i = 0; i < num_ints; ++i)
359      x.push_back(0);
360  }
361  end[2][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
362
363  start = std::clock();
364  {
365    std::list<int, fast_alloc_sync> x;
366    for (unsigned long i = 0; i < num_ints; ++i)
367      x.push_back(0);
368  }
369  end[2][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
370
371  std::cout << "Test 0: Insertion & deletion of " << num_ints << " ints in a vector:" << std::endl;
372  std::cout << "  std::allocator: " << end[0][0] << " seconds" << std::endl;
373  std::cout << "  malloc/free:    " << end[0][1] << " seconds" << std::endl;
374  std::cout << "  new/delete:     " << end[0][2] << " seconds" << std::endl;
375  std::cout << "  Pool Alloc:     " << end[0][3] << " seconds" << std::endl;
376  std::cout << "  Pool /w Sync:   " << end[0][4] << " seconds" << std::endl;
377  std::cout << "  Pool:           not possible" << std::endl;
378  std::cout << "Test 1: Insertion & deletion of " << num_ints << " ints in a set:" << std::endl;
379  std::cout << "  std::allocator: " << end[1][0] << " seconds" << std::endl;
380  std::cout << "  malloc/free:    " << end[1][1] << " seconds" << std::endl;
381  std::cout << "  new/delete:     " << end[1][2] << " seconds" << std::endl;
382  std::cout << "  Pool Alloc:     " << end[1][3] << " seconds" << std::endl;
383  std::cout << "  Pool /w Sync:   " << end[1][4] << " seconds" << std::endl;
384  std::cout << "  Pool:           not possible" << std::endl;
385  std::cout << "Test 2: Insertion & deletion of " << num_ints << " ints in a list:" << std::endl;
386  std::cout << "  std::allocator: " << end[2][0] << " seconds" << std::endl;
387  std::cout << "  malloc/free:    " << end[2][1] << " seconds" << std::endl;
388  std::cout << "  new/delete:     " << end[2][2] << " seconds" << std::endl;
389  std::cout << "  Pool Alloc:     " << end[2][3] << " seconds" << std::endl;
390  std::cout << "  Pool /w Sync:   " << end[2][4] << " seconds" << std::endl;
391  std::cout << "  Pool:           not possible" << std::endl;
392}
393
394int main(int argc, char * argv[])
395{
396  if (argc != 1 && argc != 2)
397  {
398    std::cerr << "Usage: " << argv[0]
399        << " [number_of_ints_to_use_each_try]" << std::endl;
400    return 1;
401  }
402
403  errno = 0;
404
405  if (argc == 2)
406  {
407    num_ints = std::strtoul(argv[1], 0, 10);
408    if (errno != 0)
409    {
410      std::cerr << "Cannot convert number \"" << argv[1] << '"' << std::endl;
411      return 2;
412    }
413  }
414  else
415    num_ints = 700000;
416
417  try
418  {
419    timing_test_containers();
420    timing_test_alloc();
421    test_number = 5;
422    timing_test_alloc_larger<64>();
423    test_number = 6;
424    timing_test_alloc_larger<256>();
425    test_number = 7;
426    timing_test_alloc_larger<4096>();
427  }
428  catch (const std::bad_alloc &)
429  {
430    std::cerr << "Timing tests ran out of memory; try again with a lower value for number of ints"
431        << " (current value is " << num_ints << ")" << std::endl;
432    return 3;
433  }
434  catch (const std::exception & e)
435  {
436    std::cerr << "Error: " << e.what() << std::endl;
437    return 4;
438  }
439  catch (...)
440  {
441    std::cerr << "Unknown error" << std::endl;
442    return 5;
443  }
444
445  return 0;
446}
447
448
Note: See TracBrowser for help on using the repository browser.