time_pool_alloc.cpp

来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 449 行

CPP
449
字号
// 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;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();  {    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 (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 (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 (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 (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();  {    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();  {    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 (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 (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 (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 (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();  {    boost::pool<> p(sizeof(int));    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);  start = std::clock();  {    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 (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 (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 (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 (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();  {    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();  {    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();  {    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();  {    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();  {    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();  {    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();  {    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();  {    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();  {    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();  {    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();  {    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();  {    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();  {    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();  {    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();  {    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();  {    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;  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;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?