123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558 |
- // Copyright (C) 2000, 2001 Stephen Cleary
- //
- // 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)
- #include <boost/pool/pool_alloc.hpp>
- #include <boost/pool/object_pool.hpp>
- #include <iostream>
- #include <vector>
- #include <list>
- #include <set>
- #include <ctime>
- #include <cerrno>
- #include "sys_allocator.hpp"
- unsigned long num_ints;
- unsigned long num_loops = 10;
- unsigned l;
- template <unsigned N>
- struct larger_structure
- {
- char data[N];
- };
- unsigned test_number;
- template <unsigned N>
- static void timing_test_alloc_larger()
- {
- typedef boost::fast_pool_allocator<larger_structure<N>,
- boost::default_user_allocator_new_delete,
- boost::details::pool::null_mutex> alloc;
- typedef boost::fast_pool_allocator<larger_structure<N> > alloc_sync;
- double end[1][6];
- std::clock_t start;
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- std::allocator<larger_structure<N> > a;
- for (unsigned long i = 0; i < num_ints; ++i)
- a.deallocate(a.allocate(1), 1);
- }
- end[0][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- for (unsigned long i = 0; i < num_ints; ++i)
- std::free(std::malloc(sizeof(larger_structure<N>)));
- }
- end[0][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- for (unsigned long i = 0; i < num_ints; ++i)
- delete new (std::nothrow) larger_structure<N>;
- }
- end[0][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- for (unsigned long i = 0; i < num_ints; ++i)
- alloc::deallocate(alloc::allocate());
- }
- end[0][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- for (unsigned long i = 0; i < num_ints; ++i)
- alloc_sync::deallocate(alloc_sync::allocate());
- }
- end[0][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- boost::pool<> p(sizeof(larger_structure<N>));
- for (unsigned long i = 0; i < num_ints; ++i)
- {
- void * const t = p.malloc();
- if (t != 0)
- p.free(t);
- }
- }
- end[0][5] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- std::cout << "Test " << test_number++ << ": Alloc & Dealloc " << num_ints << " structures of size " << sizeof(larger_structure<N>) << ":" << std::endl;
- std::cout << " std::allocator: " << end[0][0] << " seconds" << std::endl;
- std::cout << " malloc/free: " << end[0][1] << " seconds" << std::endl;
- std::cout << " new/delete: " << end[0][2] << " seconds" << std::endl;
- std::cout << " Pool Alloc: " << end[0][3] << " seconds" << std::endl;
- std::cout << " Pool /w Sync: " << end[0][4] << " seconds" << std::endl;
- std::cout << " Pool: " << end[0][5] << " seconds" << std::endl;
- }
- static void timing_test_alloc()
- {
- typedef boost::fast_pool_allocator<int,
- boost::default_user_allocator_new_delete,
- boost::details::pool::null_mutex> alloc;
- typedef boost::fast_pool_allocator<int> alloc_sync;
- double end[2][6];
- std::clock_t start;
- int ** p = new int*[num_ints];
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- std::allocator<int> a;
- for (unsigned long i = 0; i < num_ints; ++i)
- a.deallocate(a.allocate(1), 1);
- }
- end[0][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- for (unsigned long i = 0; i < num_ints; ++i)
- std::free(std::malloc(sizeof(int)));
- }
- end[0][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- for (unsigned long i = 0; i < num_ints; ++i)
- delete new (std::nothrow) int;
- }
- end[0][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- for (unsigned long i = 0; i < num_ints; ++i)
- alloc::deallocate(alloc::allocate());
- }
- end[0][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- for (unsigned long i = 0; i < num_ints; ++i)
- alloc_sync::deallocate(alloc_sync::allocate());
- }
- end[0][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- boost::pool<> p2(sizeof(int));
- for (unsigned long i = 0; i < num_ints; ++i)
- {
- void * const t = p2.malloc();
- if (t != 0)
- p2.free(t);
- }
- }
- end[0][5] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- std::allocator<int> a;
- for (unsigned long i = 0; i < num_ints; ++i)
- p[i] = a.allocate(1);
- for (unsigned long i = 0; i < num_ints; ++i)
- a.deallocate(p[i], 1);
- }
- end[1][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- for (unsigned long i = 0; i < num_ints; ++i)
- p[i] = (int *) std::malloc(sizeof(int));
- for (unsigned long i = 0; i < num_ints; ++i)
- std::free(p[i]);
- }
- end[1][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- for (unsigned long i = 0; i < num_ints; ++i)
- p[i] = new (std::nothrow) int;
- for (unsigned long i = 0; i < num_ints; ++i)
- delete p[i];
- }
- end[1][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- for (unsigned long i = 0; i < num_ints; ++i)
- p[i] = alloc::allocate();
- for (unsigned long i = 0; i < num_ints; ++i)
- alloc::deallocate(p[i]);
- }
- end[1][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- for (unsigned long i = 0; i < num_ints; ++i)
- p[i] = alloc_sync::allocate();
- for (unsigned long i = 0; i < num_ints; ++i)
- alloc_sync::deallocate(p[i]);
- }
- end[1][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- boost::pool<> pl(sizeof(int));
- for (unsigned long i = 0; i < num_ints; ++i)
- p[i] = reinterpret_cast<int *>(pl.malloc());
- for (unsigned long i = 0; i < num_ints; ++i)
- if (p[i] != 0)
- pl.free(p[i]);
- }
- end[1][5] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- delete [] p;
- std::cout << "Test 3: Alloc & Dealloc " << num_ints << " ints:" << std::endl;
- std::cout << " std::allocator: " << end[0][0] << " seconds" << std::endl;
- std::cout << " malloc/free: " << end[0][1] << " seconds" << std::endl;
- std::cout << " new/delete: " << end[0][2] << " seconds" << std::endl;
- std::cout << " Pool Alloc: " << end[0][3] << " seconds" << std::endl;
- std::cout << " Pool /w Sync: " << end[0][4] << " seconds" << std::endl;
- std::cout << " Pool: " << end[0][5] << " seconds" << std::endl;
- std::cout << "Test 4: Alloc " << num_ints << " ints & Dealloc " << num_ints << " ints:" << std::endl;
- std::cout << " std::allocator: " << end[1][0] << " seconds" << std::endl;
- std::cout << " malloc/free: " << end[1][1] << " seconds" << std::endl;
- std::cout << " new/delete: " << end[1][2] << " seconds" << std::endl;
- std::cout << " Pool Alloc: " << end[1][3] << " seconds" << std::endl;
- std::cout << " Pool /w Sync: " << end[1][4] << " seconds" << std::endl;
- std::cout << " Pool: " << end[1][5] << " seconds" << std::endl;
- }
- static void timing_test_containers()
- {
- typedef boost::pool_allocator<int,
- boost::default_user_allocator_new_delete,
- boost::details::pool::null_mutex> alloc;
- typedef boost::pool_allocator<int> alloc_sync;
- typedef boost::fast_pool_allocator<int,
- boost::default_user_allocator_new_delete,
- boost::details::pool::null_mutex> fast_alloc;
- typedef boost::fast_pool_allocator<int> fast_alloc_sync;
- double end[3][5];
- std::clock_t start;
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- std::vector<int, std::allocator<int> > x;
- for (unsigned long i = 0; i < num_ints; ++i)
- x.push_back(0);
- }
- end[0][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- std::vector<int, malloc_allocator<int> > x;
- for (unsigned long i = 0; i < num_ints; ++i)
- x.push_back(0);
- }
- end[0][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- std::vector<int, new_delete_allocator<int> > x;
- for (unsigned long i = 0; i < num_ints; ++i)
- x.push_back(0);
- }
- end[0][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- std::vector<int, alloc> x;
- for (unsigned long i = 0; i < num_ints; ++i)
- x.push_back(0);
- }
- end[0][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- std::vector<int, alloc_sync> x;
- for (unsigned long i = 0; i < num_ints; ++i)
- x.push_back(0);
- }
- end[0][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- std::set<int, std::less<int>, std::allocator<int> > x;
- for (unsigned long i = 0; i < num_ints; ++i)
- x.insert(0);
- }
- end[1][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- std::set<int, std::less<int>, malloc_allocator<int> > x;
- for (unsigned long i = 0; i < num_ints; ++i)
- x.insert(0);
- }
- end[1][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- std::set<int, std::less<int>, new_delete_allocator<int> > x;
- for (unsigned long i = 0; i < num_ints; ++i)
- x.insert(0);
- }
- end[1][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- std::set<int, std::less<int>, fast_alloc> x;
- for (unsigned long i = 0; i < num_ints; ++i)
- x.insert(0);
- }
- end[1][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- std::set<int, std::less<int>, fast_alloc_sync> x;
- for (unsigned long i = 0; i < num_ints; ++i)
- x.insert(0);
- }
- end[1][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- std::list<int, std::allocator<int> > x;
- for (unsigned long i = 0; i < num_ints; ++i)
- x.push_back(0);
- }
- end[2][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- std::list<int, malloc_allocator<int> > x;
- for (unsigned long i = 0; i < num_ints; ++i)
- x.push_back(0);
- }
- end[2][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- std::list<int, new_delete_allocator<int> > x;
- for (unsigned long i = 0; i < num_ints; ++i)
- x.push_back(0);
- }
- end[2][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- std::list<int, fast_alloc> x;
- for (unsigned long i = 0; i < num_ints; ++i)
- x.push_back(0);
- }
- end[2][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- start = std::clock();
- for(l = 0; l < num_loops; ++l)
- {
- std::list<int, fast_alloc_sync> x;
- for (unsigned long i = 0; i < num_ints; ++i)
- x.push_back(0);
- }
- end[2][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
- std::cout << "Test 0: Insertion & deletion of " << num_ints << " ints in a vector:" << std::endl;
- std::cout << " std::allocator: " << end[0][0] << " seconds" << std::endl;
- std::cout << " malloc/free: " << end[0][1] << " seconds" << std::endl;
- std::cout << " new/delete: " << end[0][2] << " seconds" << std::endl;
- std::cout << " Pool Alloc: " << end[0][3] << " seconds" << std::endl;
- std::cout << " Pool /w Sync: " << end[0][4] << " seconds" << std::endl;
- std::cout << " Pool: not possible" << std::endl;
- std::cout << "Test 1: Insertion & deletion of " << num_ints << " ints in a set:" << std::endl;
- std::cout << " std::allocator: " << end[1][0] << " seconds" << std::endl;
- std::cout << " malloc/free: " << end[1][1] << " seconds" << std::endl;
- std::cout << " new/delete: " << end[1][2] << " seconds" << std::endl;
- std::cout << " Pool Alloc: " << end[1][3] << " seconds" << std::endl;
- std::cout << " Pool /w Sync: " << end[1][4] << " seconds" << std::endl;
- std::cout << " Pool: not possible" << std::endl;
- std::cout << "Test 2: Insertion & deletion of " << num_ints << " ints in a list:" << std::endl;
- std::cout << " std::allocator: " << end[2][0] << " seconds" << std::endl;
- std::cout << " malloc/free: " << end[2][1] << " seconds" << std::endl;
- std::cout << " new/delete: " << end[2][2] << " seconds" << std::endl;
- std::cout << " Pool Alloc: " << end[2][3] << " seconds" << std::endl;
- std::cout << " Pool /w Sync: " << end[2][4] << " seconds" << std::endl;
- std::cout << " Pool: not possible" << std::endl;
- }
- int main(int argc, char * argv[])
- {
- if (argc != 1 && argc != 2)
- {
- std::cerr << "Usage: " << argv[0]
- << " [number_of_ints_to_use_each_try]" << std::endl;
- return 1;
- }
- errno = 0;
- if (argc == 2)
- {
- num_ints = std::strtoul(argv[1], 0, 10);
- if (errno != 0)
- {
- std::cerr << "Cannot convert number \"" << argv[1] << '"' << std::endl;
- return 2;
- }
- }
- else
- num_ints = 700000;
- #ifndef _NDEBUG
- num_ints /= 100;
- #endif
- try
- {
- timing_test_containers();
- timing_test_alloc();
- test_number = 5;
- timing_test_alloc_larger<64>();
- test_number = 6;
- timing_test_alloc_larger<256>();
- test_number = 7;
- timing_test_alloc_larger<4096>();
- }
- catch (const std::bad_alloc &)
- {
- std::cerr << "Timing tests ran out of memory; try again with a lower value for number of ints"
- << " (current value is " << num_ints << ")" << std::endl;
- return 3;
- }
- catch (const std::exception & e)
- {
- std::cerr << "Error: " << e.what() << std::endl;
- return 4;
- }
- catch (...)
- {
- std::cerr << "Unknown error" << std::endl;
- return 5;
- }
- return 0;
- }
- /*
- Output:
- MSVC 10.0 using mutli-threaded DLL
- time_pool_alloc.cpp
- Creating library J:\Cpp\pool\pool\Release\alloc_example.lib and object J:\Cpp\pool\pool\Release\alloc_example.exp
- Generating code
- Finished generating code
- alloc_example.vcxproj -> J:\Cpp\pool\pool\Release\alloc_example.exe
- Test 0: Insertion & deletion of 700000 ints in a vector:
- std::allocator: 0.062 seconds
- malloc/free: 0.078 seconds
- new/delete: 0.078 seconds
- Pool Alloc: 0.328 seconds
- Pool /w Sync: 0.343 seconds
- Pool: not possible
- Test 1: Insertion & deletion of 700000 ints in a set:
- std::allocator: 0.561 seconds
- malloc/free: 0.546 seconds
- new/delete: 0.562 seconds
- Pool Alloc: 0.109 seconds
- Pool /w Sync: 0.094 seconds
- Pool: not possible
- Test 2: Insertion & deletion of 700000 ints in a list:
- std::allocator: 0.671 seconds
- malloc/free: 0.67 seconds
- new/delete: 0.671 seconds
- Pool Alloc: 0.094 seconds
- Pool /w Sync: 0.093 seconds
- Pool: not possible
- Test 3: Alloc & Dealloc 700000 ints:
- std::allocator: 0.5 seconds
- malloc/free: 0.468 seconds
- new/delete: 0.592 seconds
- Pool Alloc: 0.032 seconds
- Pool /w Sync: 0.015 seconds
- Pool: 0.016 seconds
- Test 4: Alloc 700000 ints & Dealloc 700000 ints:
- std::allocator: 0.593 seconds
- malloc/free: 0.577 seconds
- new/delete: 0.717 seconds
- Pool Alloc: 0.032 seconds
- Pool /w Sync: 0.031 seconds
- Pool: 0.047 seconds
- Test 5: Alloc & Dealloc 700000 structures of size 64:
- std::allocator: 0.499 seconds
- malloc/free: 0.483 seconds
- new/delete: 0.624 seconds
- Pool Alloc: 0.016 seconds
- Pool /w Sync: 0.031 seconds
- Pool: 0.016 seconds
- Test 6: Alloc & Dealloc 700000 structures of size 256:
- std::allocator: 0.499 seconds
- malloc/free: 0.484 seconds
- new/delete: 0.639 seconds
- Pool Alloc: 0.016 seconds
- Pool /w Sync: 0.015 seconds
- Pool: 0.016 seconds
- Test 7: Alloc & Dealloc 700000 structures of size 4096:
- std::allocator: 0.515 seconds
- malloc/free: 0.515 seconds
- new/delete: 0.639 seconds
- Pool Alloc: 0.031 seconds
- Pool /w Sync: 0.016 seconds
- Pool: 0.016 seconds
- */
|