tags:

views:

244

answers:

3

I have to read a lot of data into:

vector<char>

A 3rd party library reads this data in many turns. In each turn it calls my callback function whose signature is like this:

CallbackFun ( int CBMsgFileItemID,
              unsigned long CBtag,
              void* CBuserInfo,
              int CBdataSize,
              void* CBdataBuffer,
              int CBisFirst,
              int CBisLast )
{

   ...

}

Currently I have implemented a buffer container using an STL Container where my method insert() and getBuff are provided to insert a new buffer and getting stored buffer. But still I want better performing code, so that I can minimize allocations and de-allocations:

template<typename T1>
class buffContainer
{
private:
     class atomBuff
     {
     private:
      atomBuff(const atomBuff& arObj);
      atomBuff operator=(const atomBuff& arObj);
      public:
      int len;
      char *buffPtr;
      atomBuff():len(0),buffPtr(NULL)
      {}
      ~atomBuff()
      {
       if(buffPtr!=NULL)
        delete []buffPtr;
      }
     };
public :
    buffContainer():_totalLen(0){}
void insert(const char const *aptr,const  unsigned long  &alen);
unsigned long getBuff(T1 &arOutObj);

private:
    std::vector<atomBuff*> moleculeBuff;
    int _totalLen;
};
template<typename T1>
void buffContainer< T1>::insert(const char const *aPtr,const  unsigned long  &aLen)
{
    if(aPtr==NULL,aLen<=0)
     return;
    atomBuff *obj=new atomBuff();
    obj->len=aLen;
    obj->buffPtr=new char[aLen];
    memcpy(obj->buffPtr,aPtr,aLen);
    _totalLen+=aLen;
    moleculeBuff.push_back(obj);

}
template<typename T1>
unsigned long buffContainer<T1>::getBuff(T1 &arOutObj)
{
    std::cout<<"Total Lenght of Data is: "<<_totalLen<<std::endl;
    if(_totalLen==0)
     return _totalLen;
    // Note : Logic pending for case size(T1) > T2::Value_Type
    int noOfObjRqd=_totalLen/sizeof(T1::value_type);
    arOutObj.resize(noOfObjRqd);
    char *ptr=(char*)(&arOutObj[0]);
    for(std::vector<atomBuff*>::const_iterator itr=moleculeBuff.begin();itr!=moleculeBuff.end();itr++)
    {
     memcpy(ptr,(*itr)->buffPtr,(*itr)->len);
     ptr+= (*itr)->len;
    }
    std::cout<<arOutObj.size()<<std::endl;

    return _totalLen;
}

How can I make this more performant?

+1  A: 

Depending on how you plan to use the result, you might try putting the incoming data into a rope datastructure instead of vector, especially if the strings you expect to come in are very large. Appending to the rope is very fast, but subsequent char-by-char traversal is slower by a constant factor. The tradeoff might work out for you or not, I don't know what you need to do with the result.

EDIT: I see from your comment this is no option, then. I don't think you can do much more efficient in the general case when the size of the data coming in is totally arbitrary. Otherwise you could try to initially reserve enough space in the vector so that the data will fit without or at most one reallocation in the average case or so.

One thing I noticed about your code:

if(aPtr==NULL,aLen<=0)

I think you mean

if(aPtr==NULL || aLen<=0)
Rüdiger Hanke
My Requirement are like : 1) Call read Function 2) Put all buffer in vector<char> 3) Give vector<char> to another module <- So (vector<char>)is fixed
sat
A: 
Jerry Coffin
+2  A: 

If my wild guess about your callback function makes sense, you don't need anything more than a vector:

std::vector<char> foo;
foo.reserve(MAGIC); // this is the important part. Reserve the right amount here.
                    // and you don't have any reallocs.
setup_callback_fun(CallbackFun, &foo);

CallbackFun ( int CBMsgFileItemID,
              unsigned long CBtag,
              void* CBuserInfo,
              int CBdataSize,
              void* CBdataBuffer,
              int CBisFirst,
              int CBisLast )
{
     std::vector<char>* pFoo = static_cast<std::vector<char>*>(CBuserInfo);

     char* data = static_cast<char*>CBdataBuffer;
     pFoo->insert(pFoo->end(), data, data+CBdataSize);
}
jmucchiello
Yes you are correct, This is right implementation
sat