#include <iostream>
#include <map>

#include <cstdio>
#include <cstdlib>
#include <ctime>

template< class Actor >
void
measure( const char * operation_name, Actor a )
{
   std::cout << "Starting '" << operation_name << "'..." << std::endl;

   clock_t start = clock();
   int opts = a();
   clock_t finish = clock();

   double total_sec = double( finish - start ) / CLOCKS_PER_SEC;
   std::cout << "Finish '" << operation_name << "', total: "
      << total_sec << ", per opt: "
      << total_sec / opts << std::endl;
}

struct value_t
   {
      int m_dummy[ 8 ];
   };

typedef std::map< int, value_t > map_t;

inline int
random( int maximum )
   {
      return static_cast< int >(
            (static_cast< double >( std::rand() ) / RAND_MAX) * maximum );
   }

template< int MAX_ELEMENT, int MAX_ITERATIONS >
class benchmark_t
   {
   private :
      map_t m_map;

   public :
      benchmark_t()
         {
            for( int i = 0; i != MAX_ELEMENT; ++i )
               m_map[ i ] = value_t();
         }

      long
      operator()()
         {
            for( long iteration = 0; iteration != MAX_ITERATIONS; ++iteration )
               {
                  for( int i = 0; i != MAX_ELEMENT; ++i )
                     {
                        int key = random( MAX_ELEMENT );
                        m_map[ key ] = value_t();
                     }
               }

            return MAX_ELEMENT * MAX_ITERATIONS;
         }
   };

int main(int argc, char **argv)
{
   {
      benchmark_t< 1000, 10000 > small_map;

      measure( "Small map", small_map );
   }

   {
      benchmark_t< 100000, 100 > medium_map;

      measure( "Medium map", medium_map );
   }

   {
      benchmark_t< 1000000, 10 > big_map;

      measure( "Big map", big_map );
   }

   {
      benchmark_t< 10000000, 1 > huge_map;

      measure( "Huge map", huge_map );
   }
}