]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/pool/example/time_pool_alloc.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / pool / example / time_pool_alloc.cpp
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
20 unsigned long num_ints;
21 unsigned long num_loops = 10;
22 unsigned l;
23
24 template <unsigned N>
25 struct larger_structure
26 {
27 char data[N];
28 };
29
30 unsigned test_number;
31
32 template <unsigned N>
33 static void timing_test_alloc_larger()
34 {
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;
39
40 double end[1][6];
41 std::clock_t start;
42
43 start = std::clock();
44 for(l = 0; l < num_loops; ++l)
45 {
46 std::allocator<larger_structure<N> > a;
47 for (unsigned long i = 0; i < num_ints; ++i)
48 a.deallocate(a.allocate(1), 1);
49 }
50 end[0][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
51
52 start = std::clock();
53 for(l = 0; l < num_loops; ++l)
54 {
55 for (unsigned long i = 0; i < num_ints; ++i)
56 std::free(std::malloc(sizeof(larger_structure<N>)));
57 }
58 end[0][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
59
60 start = std::clock();
61 for(l = 0; l < num_loops; ++l)
62 {
63 for (unsigned long i = 0; i < num_ints; ++i)
64 delete new (std::nothrow) larger_structure<N>;
65 }
66 end[0][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
67
68 start = std::clock();
69 for(l = 0; l < num_loops; ++l)
70 {
71 for (unsigned long i = 0; i < num_ints; ++i)
72 alloc::deallocate(alloc::allocate());
73 }
74 end[0][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
75
76 start = std::clock();
77 for(l = 0; l < num_loops; ++l)
78 {
79 for (unsigned long i = 0; i < num_ints; ++i)
80 alloc_sync::deallocate(alloc_sync::allocate());
81 }
82 end[0][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
83
84 start = std::clock();
85 for(l = 0; l < num_loops; ++l)
86 {
87 boost::pool<> p(sizeof(larger_structure<N>));
88 for (unsigned long i = 0; i < num_ints; ++i)
89 {
90 void * const t = p.malloc();
91 if (t != 0)
92 p.free(t);
93 }
94 }
95 end[0][5] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
96
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;
104 }
105
106 static void timing_test_alloc()
107 {
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;
112
113 double end[2][6];
114 std::clock_t start;
115
116 int ** p = new int*[num_ints];
117
118 start = std::clock();
119 for(l = 0; l < num_loops; ++l)
120 {
121 std::allocator<int> a;
122 for (unsigned long i = 0; i < num_ints; ++i)
123 a.deallocate(a.allocate(1), 1);
124 }
125 end[0][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
126
127 start = std::clock();
128 for(l = 0; l < num_loops; ++l)
129 {
130 for (unsigned long i = 0; i < num_ints; ++i)
131 std::free(std::malloc(sizeof(int)));
132 }
133 end[0][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
134
135 start = std::clock();
136 for(l = 0; l < num_loops; ++l)
137 {
138 for (unsigned long i = 0; i < num_ints; ++i)
139 delete new (std::nothrow) int;
140 }
141 end[0][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
142
143 start = std::clock();
144 for(l = 0; l < num_loops; ++l)
145 {
146 for (unsigned long i = 0; i < num_ints; ++i)
147 alloc::deallocate(alloc::allocate());
148 }
149 end[0][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
150
151 start = std::clock();
152 for(l = 0; l < num_loops; ++l)
153 {
154 for (unsigned long i = 0; i < num_ints; ++i)
155 alloc_sync::deallocate(alloc_sync::allocate());
156 }
157 end[0][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
158
159 start = std::clock();
160 for(l = 0; l < num_loops; ++l)
161 {
162 boost::pool<> p2(sizeof(int));
163 for (unsigned long i = 0; i < num_ints; ++i)
164 {
165 void * const t = p2.malloc();
166 if (t != 0)
167 p2.free(t);
168 }
169 }
170 end[0][5] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
171
172
173 start = std::clock();
174 for(l = 0; l < num_loops; ++l)
175 {
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);
181 }
182 end[1][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
183
184 start = std::clock();
185 for(l = 0; l < num_loops; ++l)
186 {
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)
190 std::free(p[i]);
191 }
192 end[1][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
193
194 start = std::clock();
195 for(l = 0; l < num_loops; ++l)
196 {
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)
200 delete p[i];
201 }
202 end[1][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
203
204 start = std::clock();
205 for(l = 0; l < num_loops; ++l)
206 {
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]);
211 }
212 end[1][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
213
214 start = std::clock();
215 for(l = 0; l < num_loops; ++l)
216 {
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]);
221 }
222 end[1][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
223
224 start = std::clock();
225 for(l = 0; l < num_loops; ++l)
226 {
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)
231 if (p[i] != 0)
232 pl.free(p[i]);
233 }
234 end[1][5] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
235
236 delete [] p;
237
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;
245
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;
253 }
254
255 static void timing_test_containers()
256 {
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;
265
266 double end[3][5];
267 std::clock_t start;
268
269 start = std::clock();
270 for(l = 0; l < num_loops; ++l)
271 {
272 std::vector<int, std::allocator<int> > x;
273 for (unsigned long i = 0; i < num_ints; ++i)
274 x.push_back(0);
275 }
276 end[0][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
277
278 start = std::clock();
279 for(l = 0; l < num_loops; ++l)
280 {
281 std::vector<int, malloc_allocator<int> > x;
282 for (unsigned long i = 0; i < num_ints; ++i)
283 x.push_back(0);
284 }
285 end[0][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
286
287 start = std::clock();
288 for(l = 0; l < num_loops; ++l)
289 {
290 std::vector<int, new_delete_allocator<int> > x;
291 for (unsigned long i = 0; i < num_ints; ++i)
292 x.push_back(0);
293 }
294 end[0][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
295
296 start = std::clock();
297 for(l = 0; l < num_loops; ++l)
298 {
299 std::vector<int, alloc> x;
300 for (unsigned long i = 0; i < num_ints; ++i)
301 x.push_back(0);
302 }
303 end[0][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
304
305 start = std::clock();
306 for(l = 0; l < num_loops; ++l)
307 {
308 std::vector<int, alloc_sync> x;
309 for (unsigned long i = 0; i < num_ints; ++i)
310 x.push_back(0);
311 }
312 end[0][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
313
314
315 start = std::clock();
316 for(l = 0; l < num_loops; ++l)
317 {
318 std::set<int, std::less<int>, std::allocator<int> > x;
319 for (unsigned long i = 0; i < num_ints; ++i)
320 x.insert(0);
321 }
322 end[1][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
323
324 start = std::clock();
325 for(l = 0; l < num_loops; ++l)
326 {
327 std::set<int, std::less<int>, malloc_allocator<int> > x;
328 for (unsigned long i = 0; i < num_ints; ++i)
329 x.insert(0);
330 }
331 end[1][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
332
333 start = std::clock();
334 for(l = 0; l < num_loops; ++l)
335 {
336 std::set<int, std::less<int>, new_delete_allocator<int> > x;
337 for (unsigned long i = 0; i < num_ints; ++i)
338 x.insert(0);
339 }
340 end[1][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
341
342 start = std::clock();
343 for(l = 0; l < num_loops; ++l)
344 {
345 std::set<int, std::less<int>, fast_alloc> x;
346 for (unsigned long i = 0; i < num_ints; ++i)
347 x.insert(0);
348 }
349 end[1][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
350
351 start = std::clock();
352 for(l = 0; l < num_loops; ++l)
353 {
354 std::set<int, std::less<int>, fast_alloc_sync> x;
355 for (unsigned long i = 0; i < num_ints; ++i)
356 x.insert(0);
357 }
358 end[1][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
359
360
361 start = std::clock();
362 for(l = 0; l < num_loops; ++l)
363 {
364 std::list<int, std::allocator<int> > x;
365 for (unsigned long i = 0; i < num_ints; ++i)
366 x.push_back(0);
367 }
368 end[2][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
369
370 start = std::clock();
371 for(l = 0; l < num_loops; ++l)
372 {
373 std::list<int, malloc_allocator<int> > x;
374 for (unsigned long i = 0; i < num_ints; ++i)
375 x.push_back(0);
376 }
377 end[2][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
378
379 start = std::clock();
380 for(l = 0; l < num_loops; ++l)
381 {
382 std::list<int, new_delete_allocator<int> > x;
383 for (unsigned long i = 0; i < num_ints; ++i)
384 x.push_back(0);
385 }
386 end[2][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
387
388 start = std::clock();
389 for(l = 0; l < num_loops; ++l)
390 {
391 std::list<int, fast_alloc> x;
392 for (unsigned long i = 0; i < num_ints; ++i)
393 x.push_back(0);
394 }
395 end[2][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
396
397 start = std::clock();
398 for(l = 0; l < num_loops; ++l)
399 {
400 std::list<int, fast_alloc_sync> x;
401 for (unsigned long i = 0; i < num_ints; ++i)
402 x.push_back(0);
403 }
404 end[2][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
405
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;
427 }
428
429 int main(int argc, char * argv[])
430 {
431 if (argc != 1 && argc != 2)
432 {
433 std::cerr << "Usage: " << argv[0]
434 << " [number_of_ints_to_use_each_try]" << std::endl;
435 return 1;
436 }
437
438 errno = 0;
439
440 if (argc == 2)
441 {
442 num_ints = std::strtoul(argv[1], 0, 10);
443 if (errno != 0)
444 {
445 std::cerr << "Cannot convert number \"" << argv[1] << '"' << std::endl;
446 return 2;
447 }
448 }
449 else
450 num_ints = 700000;
451
452 #ifndef _NDEBUG
453 num_ints /= 100;
454 #endif
455
456 try
457 {
458 timing_test_containers();
459 timing_test_alloc();
460 test_number = 5;
461 timing_test_alloc_larger<64>();
462 test_number = 6;
463 timing_test_alloc_larger<256>();
464 test_number = 7;
465 timing_test_alloc_larger<4096>();
466 }
467 catch (const std::bad_alloc &)
468 {
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;
471 return 3;
472 }
473 catch (const std::exception & e)
474 {
475 std::cerr << "Error: " << e.what() << std::endl;
476 return 4;
477 }
478 catch (...)
479 {
480 std::cerr << "Unknown error" << std::endl;
481 return 5;
482 }
483
484 return 0;
485 }
486
487 /*
488
489 Output:
490
491 MSVC 10.0 using mutli-threaded DLL
492
493 time_pool_alloc.cpp
494 Creating library J:\Cpp\pool\pool\Release\alloc_example.lib and object J:\Cpp\pool\pool\Release\alloc_example.exp
495 Generating code
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
504 Pool: not possible
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
511 Pool: not possible
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
518 Pool: not possible
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
525 Pool: 0.016 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
532 Pool: 0.047 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
539 Pool: 0.016 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
546 Pool: 0.016 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
553 Pool: 0.016 seconds
554
555 */
556
557
558