boost object pool destroy performance

In one of my application, we wanted to achieve 8000 TPS (Transactions per second) where every second, 8000 session objects will be created and destroyed.
To achieve this performance number, I wanted to optimize memory allocation and deallocation so  started looking for existing memory pool class particularly in boost libraries (assuming it would be faster) and I am already using few classes from boost.

I found boost::object_pool.  It is a header only file so no need to include link library and I included into my application. At the same time, I used boost::multi_index_container to store session object with multiple indexes.  The performance was degrading as number of object increases in the container.  I thought that is due to boost multi-index-container.

So I created two separate test applications to measure performance of boost object pool and boost multi-index-container and found that boost object_pool was the bottleneck.

Here is the performance number of destroying 10K, 20K and 30K object from object_pool and using standard c++ delete.

./object_pool_test 10000
Total time to destroy 10000 using delete: 0.3158860
Total time to destroy 10000 from object_pool: 1.447002736 sec

./object_pool_test 20000
Total time to destroy 20000 using delete: 0.6340170
Total time to destroy 20000 from object_pool: 9.624879974 sec

./object_pool_test 30000
Total time to destroy 30000 using delete: 0.10413087
Total time to destroy 30000 from object_pool: 32.150515048 sec


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// File: test_object_pool.cpp
// Description: Test performance of deleting object from boost::object_pool versus standard delete operator.
// Author: Rohit Joshi
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 #include <iostream>
#include <vector>
#include <time.h>
#include <boost/pool/object_pool.hpp>

class Test
{
  char buffer[1024];
  unsigned long id;
};

int main(int argc, char** argv) {
   if(argc < 2) {
     std::cout << "Usage: "<< argv[0] << " NumObjects\n";
     return  0;
  }

  int num_objs = atoi(argv[1]);
/////////////////////////////////////////////////////////////////////////////////////////////////
//test1: using standard delete to delete objects
////////////////////////////////////////////////////////////////////////////////////////////////
  std::vector<Test*> vDelTest;
  vDelTest.reserve(num_objs);
  for(int i = 0; i < num_objs; ++i) {
    Test *pTest = new Test();
    vDelTest.push_back(pTest);
  }
  timespec tv;
  tv.tv_sec = 0;
  tv.tv_nsec = 0;

  clock_settime(CLOCK_PROCESS_CPUTIME_ID, &tv);

  for(int i = 0; i < num_objs; ++i) {
    delete vDelTest[i];
  }
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tv);

  std::cout << "Total time to destroy "<< num_objs << " using delete: " << tv.tv_sec << "." << tv.tv
_nsec << "\n";

//////////////////////////////////////////////////////////////////////////////////////////////////
//delete using object_pool
/////////////////////////////////////////////////////////////////////////////////////////////////
  boost::object_pool<Test> m_oPool;
  std::vector<Test*> vTest;
  vTest.reserve(num_objs);

  for(int i = 0; i < num_objs; ++i) {
    Test *pTest = m_oPool.construct();
    vTest.push_back(pTest);
  }
 
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tv);

  std::cout << "Total time to destroy "<< num_objs << " from object_pool: " << tv.tv_sec << "." << tv.tv_nsec << "\n";

  return 0;

}

To compile, copy this source into test_object_pool.cpp
 g++ -c test_object_pool.cpp
g++ -o test_object_pool test_object_pool.o -lrt