C++ String Performance 

by Lev Kochubeevsky



Listing One

#include <pthread.h>

#include "util.h"

unsigned int createStrings ( int n )

{

 static char *samples[]={"something1","something2","something3","something4"};

 printf ("Thread <%d>: Creating/destroying %d strings...\n",pthread_self(),n);

 unsigned int start = utilGetTickCount ();

 for ( int i=0; i<n; i++ )

 {

    string s ( samples[i%4] );

 }

 unsigned int end = utilGetTickCount ();

 printf ( "Thread <%d>: total time=%d millisecs, average=%f\n",

           pthread_self(), end-start, (float)(end-start)/n );

 return ( end - start );

}

int main ( int argc, char **argv )

{

  if ( argc > 2 )

  {

    printf ( "teststring1 <n_of_strings_to_create> \n" );

    return 0;

  }

  int n = 100000;

  if ( argc > 1 )

    n = atoi ( argv[1] );

  createStrings ( n );

  exit(0);

}



Listing Two

#include <pthread.h>

#include "util.h"

void *createStrings ( void *n_void )

{

 int n = (int) n_void;

 static char *samples[]={"something1","something2","something3","something4"};

 printf ("Thread <%d>: Creating/destroying %d strings...\n",pthread_self(),n);

 unsigned int start = utilGetTickCount ();

 for ( int i=0; i<n; i++ )

 {

    string s ( samples[i%4] );

 }

 unsigned int end = utilGetTickCount ();

 printf ( "Thread <%d>: total time=%d millisecs, average=%f\n", 

           pthread_self(), end-start, (float)(end-start)/n );

 return NULL;

}

int main ( int argc, char **argv )

{

  if ( argc > 3 )

  {

    printf ( 

       "teststring1 [<n_of_strings_to_create>] [<n_threads>]\n" );

    return 0;

  }

  int n = 100000;

  int n_thr = 10;

  if ( argc > 1 )

    n = atoi ( argv[1] );

  if ( argc > 2 )

    n_thr = atoi ( argv[2] );

  pthread_attr_t attr;

  pthread_attr_init ( &attr );

  pthread_t *tid = new pthread_t[n_thr];

  int i;

  // create threads

  for  ( i=0; i<n_thr; i++ )

  {

    if ( pthread_create ( &tid[i], NULL, createStrings, (void *) n ) )

    {

      printf ( "ERROR: ptread_create for thread <%d>\n", i );

      exit(-1);

    }

  }

  // wait for all threads to terminate

  for  ( i=0; i<n_thr; i++ )

    pthread_join ( tid[i], 0 );

  exit(0);

}



Listing Three

template<int bufsize>

class CGenStringT

{

public:

  CGenStringT ( const char *S = "", int bAlloc = 1 ) : m_s(m_buf)

  {

    if ( !bufsize )

 ...

private:

  char *m_s;

   int   m_bAlloc;

  char  m_buf[bufsize+1];

};



Listing Four

 ...

  CGenStringT ( const CGenStringT& rv ): m_s(m_buf)

  {

    if ( !bufsize )

    {

      if ( m_bAlloc = rv.m_bAlloc )

      {

        // make on heap

        m_s = new char [ strlen(rv.m_s)+1 ];

        strcpy ( m_s, rv.m_s );

      }

      else

        // just set a pointer

        m_s = rv.m_s;

    }

    else

    {

      // make on stack

      m_buf[bufsize] = 0;

      strncpy ( m_s, rv.m_s, bufsize );

    }

#ifdef MEM_ALLOC_DEBUG

    printf ("CGenString copy constructor called: this=%x allocation=%s"

            " ptr=%x\n", this, (!bufsize && m_bAlloc ) ? "yes":"no", m_s );

#endif

  }

 ...





Listing Five

class CMyMap

{

private:

  map < string, int > m_mymap;

public:

  void add ( const char *str, int i )

  {

    m_mymap[str] = i;

  }

  void remove ( const char *str )

  {

    m_mymap.erase ( str );

  }

  bool find ( const char *str, int *res )

  {

    map < string, int >::const_iterator ci;

    ci = m_mymap.find(str);

    bool found = ( ci != m_mymap.end() );

    if ( found )

       *res = ci->second;

    return found;

  }

};





Listing Six

class CMyMap

{

private:

  map < CGenString, int > m_mymap;

  typedef map < CGenString, int > GenStringIntMap;

public:

  void add ( const char *str, int i )

  {

    m_mymap[str] = i;

  }

  void remove ( const char *str )

  {

    FAST_STRING(s,str);

    m_mymap.erase ( s );

  }

  bool find ( const char *str, int *res )

  {

    map < CGenString, int >::const_iterator ci;

    FAST_STRING(s,str);

    ci = m_mymap.find(s);

    bool found = ( ci != m_mymap.end() );

    if ( found )

      *res = ci->second;

    return found;

  }

};









4



