1 // Copyright (C) 2000, 2001 Stephen Cleary
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)
7 #include <boost/pool/pool_alloc.hpp>
8 #include <boost/pool/object_pool.hpp>
18 #include "sys_allocator.hpp"
20 unsigned long num_ints
;
21 unsigned long num_loops
= 10;
25 struct larger_structure
33 static void timing_test_alloc_larger()
35 typedef boost::fast_pool_allocator
<larger_structure
<N
>,
36 boost::default_user_allocator_new_delete
,
37 boost::details::pool::null_mutex
> alloc
;
38 typedef boost::fast_pool_allocator
<larger_structure
<N
> > alloc_sync
;
44 for(l
= 0; l
< num_loops
; ++l
)
46 std::allocator
<larger_structure
<N
> > a
;
47 for (unsigned long i
= 0; i
< num_ints
; ++i
)
48 a
.deallocate(a
.allocate(1), 1);
50 end
[0][0] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
53 for(l
= 0; l
< num_loops
; ++l
)
55 for (unsigned long i
= 0; i
< num_ints
; ++i
)
56 std::free(std::malloc(sizeof(larger_structure
<N
>)));
58 end
[0][1] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
61 for(l
= 0; l
< num_loops
; ++l
)
63 for (unsigned long i
= 0; i
< num_ints
; ++i
)
64 delete new (std::nothrow
) larger_structure
<N
>;
66 end
[0][2] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
69 for(l
= 0; l
< num_loops
; ++l
)
71 for (unsigned long i
= 0; i
< num_ints
; ++i
)
72 alloc::deallocate(alloc::allocate());
74 end
[0][3] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
77 for(l
= 0; l
< num_loops
; ++l
)
79 for (unsigned long i
= 0; i
< num_ints
; ++i
)
80 alloc_sync::deallocate(alloc_sync::allocate());
82 end
[0][4] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
85 for(l
= 0; l
< num_loops
; ++l
)
87 boost::pool
<> p(sizeof(larger_structure
<N
>));
88 for (unsigned long i
= 0; i
< num_ints
; ++i
)
90 void * const t
= p
.malloc();
95 end
[0][5] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
97 std::cout
<< "Test " << test_number
++ << ": Alloc & Dealloc " << num_ints
<< " structures of size " << sizeof(larger_structure
<N
>) << ":" << std::endl
;
98 std::cout
<< " std::allocator: " << end
[0][0] << " seconds" << std::endl
;
99 std::cout
<< " malloc/free: " << end
[0][1] << " seconds" << std::endl
;
100 std::cout
<< " new/delete: " << end
[0][2] << " seconds" << std::endl
;
101 std::cout
<< " Pool Alloc: " << end
[0][3] << " seconds" << std::endl
;
102 std::cout
<< " Pool /w Sync: " << end
[0][4] << " seconds" << std::endl
;
103 std::cout
<< " Pool: " << end
[0][5] << " seconds" << std::endl
;
106 static void timing_test_alloc()
108 typedef boost::fast_pool_allocator
<int,
109 boost::default_user_allocator_new_delete
,
110 boost::details::pool::null_mutex
> alloc
;
111 typedef boost::fast_pool_allocator
<int> alloc_sync
;
116 int ** p
= new int*[num_ints
];
118 start
= std::clock();
119 for(l
= 0; l
< num_loops
; ++l
)
121 std::allocator
<int> a
;
122 for (unsigned long i
= 0; i
< num_ints
; ++i
)
123 a
.deallocate(a
.allocate(1), 1);
125 end
[0][0] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
127 start
= std::clock();
128 for(l
= 0; l
< num_loops
; ++l
)
130 for (unsigned long i
= 0; i
< num_ints
; ++i
)
131 std::free(std::malloc(sizeof(int)));
133 end
[0][1] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
135 start
= std::clock();
136 for(l
= 0; l
< num_loops
; ++l
)
138 for (unsigned long i
= 0; i
< num_ints
; ++i
)
139 delete new (std::nothrow
) int;
141 end
[0][2] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
143 start
= std::clock();
144 for(l
= 0; l
< num_loops
; ++l
)
146 for (unsigned long i
= 0; i
< num_ints
; ++i
)
147 alloc::deallocate(alloc::allocate());
149 end
[0][3] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
151 start
= std::clock();
152 for(l
= 0; l
< num_loops
; ++l
)
154 for (unsigned long i
= 0; i
< num_ints
; ++i
)
155 alloc_sync::deallocate(alloc_sync::allocate());
157 end
[0][4] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
159 start
= std::clock();
160 for(l
= 0; l
< num_loops
; ++l
)
162 boost::pool
<> p2(sizeof(int));
163 for (unsigned long i
= 0; i
< num_ints
; ++i
)
165 void * const t
= p2
.malloc();
170 end
[0][5] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
173 start
= std::clock();
174 for(l
= 0; l
< num_loops
; ++l
)
176 std::allocator
<int> a
;
177 for (unsigned long i
= 0; i
< num_ints
; ++i
)
178 p
[i
] = a
.allocate(1);
179 for (unsigned long i
= 0; i
< num_ints
; ++i
)
180 a
.deallocate(p
[i
], 1);
182 end
[1][0] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
184 start
= std::clock();
185 for(l
= 0; l
< num_loops
; ++l
)
187 for (unsigned long i
= 0; i
< num_ints
; ++i
)
188 p
[i
] = (int *) std::malloc(sizeof(int));
189 for (unsigned long i
= 0; i
< num_ints
; ++i
)
192 end
[1][1] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
194 start
= std::clock();
195 for(l
= 0; l
< num_loops
; ++l
)
197 for (unsigned long i
= 0; i
< num_ints
; ++i
)
198 p
[i
] = new (std::nothrow
) int;
199 for (unsigned long i
= 0; i
< num_ints
; ++i
)
202 end
[1][2] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
204 start
= std::clock();
205 for(l
= 0; l
< num_loops
; ++l
)
207 for (unsigned long i
= 0; i
< num_ints
; ++i
)
208 p
[i
] = alloc::allocate();
209 for (unsigned long i
= 0; i
< num_ints
; ++i
)
210 alloc::deallocate(p
[i
]);
212 end
[1][3] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
214 start
= std::clock();
215 for(l
= 0; l
< num_loops
; ++l
)
217 for (unsigned long i
= 0; i
< num_ints
; ++i
)
218 p
[i
] = alloc_sync::allocate();
219 for (unsigned long i
= 0; i
< num_ints
; ++i
)
220 alloc_sync::deallocate(p
[i
]);
222 end
[1][4] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
224 start
= std::clock();
225 for(l
= 0; l
< num_loops
; ++l
)
227 boost::pool
<> pl(sizeof(int));
228 for (unsigned long i
= 0; i
< num_ints
; ++i
)
229 p
[i
] = reinterpret_cast<int *>(pl
.malloc());
230 for (unsigned long i
= 0; i
< num_ints
; ++i
)
234 end
[1][5] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
238 std::cout
<< "Test 3: Alloc & Dealloc " << num_ints
<< " ints:" << std::endl
;
239 std::cout
<< " std::allocator: " << end
[0][0] << " seconds" << std::endl
;
240 std::cout
<< " malloc/free: " << end
[0][1] << " seconds" << std::endl
;
241 std::cout
<< " new/delete: " << end
[0][2] << " seconds" << std::endl
;
242 std::cout
<< " Pool Alloc: " << end
[0][3] << " seconds" << std::endl
;
243 std::cout
<< " Pool /w Sync: " << end
[0][4] << " seconds" << std::endl
;
244 std::cout
<< " Pool: " << end
[0][5] << " seconds" << std::endl
;
246 std::cout
<< "Test 4: Alloc " << num_ints
<< " ints & Dealloc " << num_ints
<< " ints:" << std::endl
;
247 std::cout
<< " std::allocator: " << end
[1][0] << " seconds" << std::endl
;
248 std::cout
<< " malloc/free: " << end
[1][1] << " seconds" << std::endl
;
249 std::cout
<< " new/delete: " << end
[1][2] << " seconds" << std::endl
;
250 std::cout
<< " Pool Alloc: " << end
[1][3] << " seconds" << std::endl
;
251 std::cout
<< " Pool /w Sync: " << end
[1][4] << " seconds" << std::endl
;
252 std::cout
<< " Pool: " << end
[1][5] << " seconds" << std::endl
;
255 static void timing_test_containers()
257 typedef boost::pool_allocator
<int,
258 boost::default_user_allocator_new_delete
,
259 boost::details::pool::null_mutex
> alloc
;
260 typedef boost::pool_allocator
<int> alloc_sync
;
261 typedef boost::fast_pool_allocator
<int,
262 boost::default_user_allocator_new_delete
,
263 boost::details::pool::null_mutex
> fast_alloc
;
264 typedef boost::fast_pool_allocator
<int> fast_alloc_sync
;
269 start
= std::clock();
270 for(l
= 0; l
< num_loops
; ++l
)
272 std::vector
<int, std::allocator
<int> > x
;
273 for (unsigned long i
= 0; i
< num_ints
; ++i
)
276 end
[0][0] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
278 start
= std::clock();
279 for(l
= 0; l
< num_loops
; ++l
)
281 std::vector
<int, malloc_allocator
<int> > x
;
282 for (unsigned long i
= 0; i
< num_ints
; ++i
)
285 end
[0][1] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
287 start
= std::clock();
288 for(l
= 0; l
< num_loops
; ++l
)
290 std::vector
<int, new_delete_allocator
<int> > x
;
291 for (unsigned long i
= 0; i
< num_ints
; ++i
)
294 end
[0][2] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
296 start
= std::clock();
297 for(l
= 0; l
< num_loops
; ++l
)
299 std::vector
<int, alloc
> x
;
300 for (unsigned long i
= 0; i
< num_ints
; ++i
)
303 end
[0][3] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
305 start
= std::clock();
306 for(l
= 0; l
< num_loops
; ++l
)
308 std::vector
<int, alloc_sync
> x
;
309 for (unsigned long i
= 0; i
< num_ints
; ++i
)
312 end
[0][4] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
315 start
= std::clock();
316 for(l
= 0; l
< num_loops
; ++l
)
318 std::set
<int, std::less
<int>, std::allocator
<int> > x
;
319 for (unsigned long i
= 0; i
< num_ints
; ++i
)
322 end
[1][0] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
324 start
= std::clock();
325 for(l
= 0; l
< num_loops
; ++l
)
327 std::set
<int, std::less
<int>, malloc_allocator
<int> > x
;
328 for (unsigned long i
= 0; i
< num_ints
; ++i
)
331 end
[1][1] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
333 start
= std::clock();
334 for(l
= 0; l
< num_loops
; ++l
)
336 std::set
<int, std::less
<int>, new_delete_allocator
<int> > x
;
337 for (unsigned long i
= 0; i
< num_ints
; ++i
)
340 end
[1][2] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
342 start
= std::clock();
343 for(l
= 0; l
< num_loops
; ++l
)
345 std::set
<int, std::less
<int>, fast_alloc
> x
;
346 for (unsigned long i
= 0; i
< num_ints
; ++i
)
349 end
[1][3] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
351 start
= std::clock();
352 for(l
= 0; l
< num_loops
; ++l
)
354 std::set
<int, std::less
<int>, fast_alloc_sync
> x
;
355 for (unsigned long i
= 0; i
< num_ints
; ++i
)
358 end
[1][4] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
361 start
= std::clock();
362 for(l
= 0; l
< num_loops
; ++l
)
364 std::list
<int, std::allocator
<int> > x
;
365 for (unsigned long i
= 0; i
< num_ints
; ++i
)
368 end
[2][0] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
370 start
= std::clock();
371 for(l
= 0; l
< num_loops
; ++l
)
373 std::list
<int, malloc_allocator
<int> > x
;
374 for (unsigned long i
= 0; i
< num_ints
; ++i
)
377 end
[2][1] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
379 start
= std::clock();
380 for(l
= 0; l
< num_loops
; ++l
)
382 std::list
<int, new_delete_allocator
<int> > x
;
383 for (unsigned long i
= 0; i
< num_ints
; ++i
)
386 end
[2][2] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
388 start
= std::clock();
389 for(l
= 0; l
< num_loops
; ++l
)
391 std::list
<int, fast_alloc
> x
;
392 for (unsigned long i
= 0; i
< num_ints
; ++i
)
395 end
[2][3] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
397 start
= std::clock();
398 for(l
= 0; l
< num_loops
; ++l
)
400 std::list
<int, fast_alloc_sync
> x
;
401 for (unsigned long i
= 0; i
< num_ints
; ++i
)
404 end
[2][4] = (std::clock() - start
) / ((double) CLOCKS_PER_SEC
);
406 std::cout
<< "Test 0: Insertion & deletion of " << num_ints
<< " ints in a vector:" << std::endl
;
407 std::cout
<< " std::allocator: " << end
[0][0] << " seconds" << std::endl
;
408 std::cout
<< " malloc/free: " << end
[0][1] << " seconds" << std::endl
;
409 std::cout
<< " new/delete: " << end
[0][2] << " seconds" << std::endl
;
410 std::cout
<< " Pool Alloc: " << end
[0][3] << " seconds" << std::endl
;
411 std::cout
<< " Pool /w Sync: " << end
[0][4] << " seconds" << std::endl
;
412 std::cout
<< " Pool: not possible" << std::endl
;
413 std::cout
<< "Test 1: Insertion & deletion of " << num_ints
<< " ints in a set:" << std::endl
;
414 std::cout
<< " std::allocator: " << end
[1][0] << " seconds" << std::endl
;
415 std::cout
<< " malloc/free: " << end
[1][1] << " seconds" << std::endl
;
416 std::cout
<< " new/delete: " << end
[1][2] << " seconds" << std::endl
;
417 std::cout
<< " Pool Alloc: " << end
[1][3] << " seconds" << std::endl
;
418 std::cout
<< " Pool /w Sync: " << end
[1][4] << " seconds" << std::endl
;
419 std::cout
<< " Pool: not possible" << std::endl
;
420 std::cout
<< "Test 2: Insertion & deletion of " << num_ints
<< " ints in a list:" << std::endl
;
421 std::cout
<< " std::allocator: " << end
[2][0] << " seconds" << std::endl
;
422 std::cout
<< " malloc/free: " << end
[2][1] << " seconds" << std::endl
;
423 std::cout
<< " new/delete: " << end
[2][2] << " seconds" << std::endl
;
424 std::cout
<< " Pool Alloc: " << end
[2][3] << " seconds" << std::endl
;
425 std::cout
<< " Pool /w Sync: " << end
[2][4] << " seconds" << std::endl
;
426 std::cout
<< " Pool: not possible" << std::endl
;
429 int main(int argc
, char * argv
[])
431 if (argc
!= 1 && argc
!= 2)
433 std::cerr
<< "Usage: " << argv
[0]
434 << " [number_of_ints_to_use_each_try]" << std::endl
;
442 num_ints
= std::strtoul(argv
[1], 0, 10);
445 std::cerr
<< "Cannot convert number \"" << argv
[1] << '"' << std::endl
;
458 timing_test_containers();
461 timing_test_alloc_larger
<64>();
463 timing_test_alloc_larger
<256>();
465 timing_test_alloc_larger
<4096>();
467 catch (const std::bad_alloc
&)
469 std::cerr
<< "Timing tests ran out of memory; try again with a lower value for number of ints"
470 << " (current value is " << num_ints
<< ")" << std::endl
;
473 catch (const std::exception
& e
)
475 std::cerr
<< "Error: " << e
.what() << std::endl
;
480 std::cerr
<< "Unknown error" << std::endl
;
491 MSVC 10.0 using mutli-threaded DLL
494 Creating library J:\Cpp\pool\pool\Release\alloc_example.lib and object J:\Cpp\pool\pool\Release\alloc_example.exp
496 Finished generating code
497 alloc_example.vcxproj -> J:\Cpp\pool\pool\Release\alloc_example.exe
498 Test 0: Insertion & deletion of 700000 ints in a vector:
499 std::allocator: 0.062 seconds
500 malloc/free: 0.078 seconds
501 new/delete: 0.078 seconds
502 Pool Alloc: 0.328 seconds
503 Pool /w Sync: 0.343 seconds
505 Test 1: Insertion & deletion of 700000 ints in a set:
506 std::allocator: 0.561 seconds
507 malloc/free: 0.546 seconds
508 new/delete: 0.562 seconds
509 Pool Alloc: 0.109 seconds
510 Pool /w Sync: 0.094 seconds
512 Test 2: Insertion & deletion of 700000 ints in a list:
513 std::allocator: 0.671 seconds
514 malloc/free: 0.67 seconds
515 new/delete: 0.671 seconds
516 Pool Alloc: 0.094 seconds
517 Pool /w Sync: 0.093 seconds
519 Test 3: Alloc & Dealloc 700000 ints:
520 std::allocator: 0.5 seconds
521 malloc/free: 0.468 seconds
522 new/delete: 0.592 seconds
523 Pool Alloc: 0.032 seconds
524 Pool /w Sync: 0.015 seconds
526 Test 4: Alloc 700000 ints & Dealloc 700000 ints:
527 std::allocator: 0.593 seconds
528 malloc/free: 0.577 seconds
529 new/delete: 0.717 seconds
530 Pool Alloc: 0.032 seconds
531 Pool /w Sync: 0.031 seconds
533 Test 5: Alloc & Dealloc 700000 structures of size 64:
534 std::allocator: 0.499 seconds
535 malloc/free: 0.483 seconds
536 new/delete: 0.624 seconds
537 Pool Alloc: 0.016 seconds
538 Pool /w Sync: 0.031 seconds
540 Test 6: Alloc & Dealloc 700000 structures of size 256:
541 std::allocator: 0.499 seconds
542 malloc/free: 0.484 seconds
543 new/delete: 0.639 seconds
544 Pool Alloc: 0.016 seconds
545 Pool /w Sync: 0.015 seconds
547 Test 7: Alloc & Dealloc 700000 structures of size 4096:
548 std::allocator: 0.515 seconds
549 malloc/free: 0.515 seconds
550 new/delete: 0.639 seconds
551 Pool Alloc: 0.031 seconds
552 Pool /w Sync: 0.016 seconds