Std :: vector push_back - bottleneck

Here is what my algorithm does: It takes a long std :: string and divides it into words and auxiliary words based on if it is larger than the width:

inline void extractWords(std::vector<std::string> &words, std::string &text,const AguiFont &font, int maxWidth)
{


    words.clear();

    int searchStart = 0;
    int curSearchPos = 0;
    char right;
    for(size_t i = 0; i < text.length(); ++i)
    {
        curSearchPos = i;

        //check if a space is to the right
        if( i == text.length() - 1)
            right = 'a';
        else
            right = text[i + 1];

        //sub divide the string if it;s too big
        int subStrWidth = 0;
        int subStrLen = 0;
        for(int x = searchStart; x < (curSearchPos - searchStart) + 1; ++x)
        {
            subStrWidth += font.getTextWidth(&text[x]);
            subStrLen ++;
        }
        if(subStrLen > maxWidth && subStrLen > 1)
        {
            for(int k = 2; k <= subStrLen; ++k)
            {
                subStrWidth = 0;
                for(int p = 0; p < k; ++p)
                {
                    subStrWidth += font.getTextWidth(&text[searchStart + p]);
                }
                if(subStrWidth > maxWidth)
                {
                    searchStart += k - 1;

                    words.push_back(text.substr(searchStart,k - 1));
                    break;

                }
            }
        }

        //add the word
        if((text[i] == ' ' && right != ' ' ) || i == text.length() - 1)
        {

                if(searchStart > 0)
                {
                    words.push_back(text.substr(searchStart ,(curSearchPos - searchStart) + 1));

                }
                else
                {
                    words.push_back(text.substr(0 ,(curSearchPos - searchStart) ));
                    words.back() += text[curSearchPos];

                }

            searchStart = i + 1 ;
        }
    }


}

As you can see, I use std :: vectors to enter my words. The vector is specified by reference. This std :: vector is static and its in proc, which calls extractWord. Oddly enough, the static caused a much greater processor consumption. After profiling, I saw that I do a lot of heap allocations, but I don’t know why, since std :: vector has to keep its elements even after the vector is cleared. Maybe a less intense way to do this? The length of the string is unknown, as well as the number of resulting strings, so I chose std :: vector, but is there a better way?

thank

* , , -

+3
5

, , std::vector<T>::reserve, . , push_back .

, , . , , . ( , , ++ 0x.)

, , , , push_back , , , , . , std::string .

+11

, , . deque . , , , .

0

, . , "". std::vector<std::string> &words - std::vector< counted_ptr<std::string> > &words. , counted_ptr < > .

, Heisenbug, auto_ptr < > , STL.

0

-, vector&. .

clear() . , . :

void clear() { vector tmp; swap(tmp); }

resize(0) clear(), .

:

  • , , .
  • C-, , , .
  • std::pair<const char*, const char*> std::string .
0

, , , . :

  • :

    : std::vector < std::string > &

    to: std::vector < std::string * > &

    , .

  • vector:: reserve, , . text.length()/maxWidth.

  • Pay close attention to the string operations that are used. It is very possible that there are many temporary lines that are generated and immediately discarded. The best way to find out if this happens is to go through the line control strings and see if there are additional line constructors and copy constructors.

0
source

Source: https://habr.com/ru/post/1688834/


All Articles