> > OK, this seems to explain most of the issue.
> > What's the ratio t(multi_index)/t(manual) in debug and
> > release modes after suppresing safe mode and invariant-
> > checking?

In both cases the ratio is more or less the same. So, it is 
between 3.28 and 3.62, depending of execution.

I have tested with only a ordered-unique index and the ratio
was 2.59, and also with only a hashed-unique index and the 
result was 1.10.

[...]
> > Other than this I can't be much more helpful. If you're
> > in a position to provide me with a complete example program
> > that I can play with I'll sure have a deeper look.

Here you have it.... 


#include <boost/lexical_cast.hpp>
#include <sys/time.h>
#include <unistd.h>
#include <iostream>

#if defined(NDEBUG)
#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
#endif

#include <map>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/composite_key.hpp>

using namespace boost::multi_index;

//////////////////////////////////////
// Types declarations
//////////////////////////////////////
enum PRIORITY_LEVEL {
  PRIORITY_EXPRESS,
  PRIORITY_HIGH,  
  PRIORITY_DEFAULT,
  PRIORITY_LOW,
  PRIORITY_NULL
};

struct TElementRec {
  PRIORITY_LEVEL  priority;
  std::string     key;  
  std::string     content;

  TElementRec():
    priority(PRIORITY_DEFAULT){}
  TElementRec( const PRIORITY_LEVEL &priority, const std::string &key, const std::string &content ):
    priority(priority), key(key), content(content){}
  TElementRec( const TElementRec &rec ) {
    priority        = rec.priority;
    key             = rec.key;
    content         = rec.content;
  }
  TElementRec & operator = ( const TElementRec &rec ) {
    priority        = rec.priority;
    key             = rec.key;
    content         = rec.content;
    return( *this ); 
  }
};

// Tags
struct TMainIndexTag{};
struct TKeyIndexTag{};

// Multi index container definition
typedef multi_index_container<
  TElementRec,
  indexed_by<
    ordered_unique< 
      tag<TMainIndexTag>,
      composite_key<
        TElementRec,
        BOOST_MULTI_INDEX_MEMBER(TElementRec,PRIORITY_LEVEL,priority),
        BOOST_MULTI_INDEX_MEMBER(TElementRec,std::string,key)
      >
    >,
    hashed_unique<
      tag<TKeyIndexTag>,
      BOOST_MULTI_INDEX_MEMBER(TElementRec,std::string,key)
    >
  >
> TElementsMIContainer;

// MANUAL DECLARATIONS
//////////////////////
struct TProcessRec {
   std::string content;

   TProcessRec() {
   };
   TProcessRec( const std::string &msg ) {
      this->content           = msg;
   };
   TProcessRec( const TProcessRec &pRec ) {
      content              = pRec.content;
   }
   TProcessRec & operator = ( const TProcessRec &pRec ) {
      content              = pRec.content;
      return( *this );
   }
};

struct QueueMsgKey {
  std::string     key;
  PRIORITY_LEVEL  priority;

  QueueMsgKey(const std::string &_key, const PRIORITY_LEVEL &_priority) {
    key   = _key;
    priority  = _priority;
  }
  QueueMsgKey(const std::string &_key) {
    key   = _key;
    priority  = PRIORITY_DEFAULT; 
  }
  QueueMsgKey() {
    priority = PRIORITY_DEFAULT;
  }
  QueueMsgKey & operator = ( const  QueueMsgKey &pRec ) {
     priority              = pRec.priority;
     key               = pRec.key;
     return( *this );
  }
};

struct QueueMsgKeyLess {
    bool operator()(const  QueueMsgKey k1, const  QueueMsgKey k2) const 
    {  return k1.priority!=k2.priority ? k1.priority>k2.priority : k1.key<k2.key; }
};

struct MsgKeyLess {
    bool operator()(const  std::string k1, const  std::string k2) const 
    {  return k1<k2; }
};

typedef std::map< QueueMsgKey, TProcessRec, QueueMsgKeyLess > TInProcessList;
typedef std::map< QueueMsgKey, TProcessRec, QueueMsgKeyLess > :: iterator TProcessListIterator;
typedef std::map< std::string, TProcessListIterator, MsgKeyLess > TRefList;
typedef std::map< std::string, TProcessListIterator, MsgKeyLess > :: iterator TRefListIterator;

//////////////////////////////////////
// Code
//////////////////////////////////////
int getMicroSecondsPassed( int &timestamp, int &microSeconds )
{
  int lTimestamp = time(NULL);
  struct timeval tv;
  gettimeofday(&tv, NULL);
  char msecs[ 20 ];
  sprintf( msecs, "%d", tv.tv_usec );
  std::string strMSecs = msecs;
  int lMicroSeconds = boost::lexical_cast<int>( strMSecs );

  if ( !timestamp ) {
    timestamp     = lTimestamp;
    microSeconds  = lMicroSeconds;
    return 0;
  }
  return (lTimestamp-timestamp)* 1000000 + (lMicroSeconds-microSeconds);
}

bool insert(const QueueMsgKey  &qkey, const TProcessRec &data)
{
  TInProcessList process_list;
  TRefList ref_list;

  TRefListIterator itr = ref_list.find( qkey.key );
  if ( itr == ref_list.end() ) {
    std::pair< TProcessListIterator, bool > result = process_list.insert( std::make_pair( qkey, data) );
    if(result.second == true) {
      ref_list[qkey.key] = result.first;
      return true;
    }
    else {
      return false;
    }
  }
  return false;
}

int main( int argc, char** argv ){
  int firstTime         = 0;
  int firstMicroSeconds = 0;
  TElementsMIContainer  elMIContainer;
  PRIORITY_LEVEL priority = PRIORITY_DEFAULT;
  std::string content     = "...";
  std::string key;

  // Multi-index container performance test
  ////////////////////////////////////////////
  getMicroSecondsPassed( firstTime, firstMicroSeconds );
  for ( int i=0; i<100000; i++ ) {
    // Changing only the key
    key = "A0000" + boost::lexical_cast<std::string>(i);
    elMIContainer.insert( TElementRec( priority, key, content ));
  }
  int multiindexTime = getMicroSecondsPassed( firstTime, firstMicroSeconds );
  std::cout << "<TQueueScheduler> Total microseconds : " << multiindexTime << std::endl;

  firstTime         = 0;
  firstMicroSeconds = 0;
  // Manual containers performance test
  ////////////////////////////////////////////
  getMicroSecondsPassed( firstTime, firstMicroSeconds );
  for ( int i=0; i<100000; i++ ) {
    // Changing only the key
    QueueMsgKey qack_key( "A0000" + boost::lexical_cast<std::string>(i) );
    insert( qack_key, TProcessRec( "..." ) );
  }
  int manualTime = getMicroSecondsPassed( firstTime, firstMicroSeconds );
  std::cout << "<TOutProcessList> Total microseconds : " << manualTime << std::endl;

  std::cout << "RATIO=" << (float)multiindexTime / manualTime << std::endl;
}


Thanks a lot for your time
  
Àngel Suñé Martí