Помогите с оптимизацией этого индекса для строки столбца и наоборот алгоритма - PullRequest
1 голос
/ 16 марта 2011

Вот моя проблема.Я сделал TextBox для моего Gui в моей игре.

Что происходит, каждый раз, когда я изменяю его размер, так как он переносится по слову, мне нужно выяснить, какой индекс содержит курсор в текстовой строке, а затем преобразовать его в соответствующий столбец строки послеРеиз.Самая медленная часть, согласно моему профилировщику, - это когда я получаю следующий символ юникода для оценки:

int AguiTextBox::indexFromColumnRow( int column, int row, bool includeUnwantedChars ) const
    {
        size_t rowLen = 0;

        int retIndex = -1;
        int bytesSkipped = 0;
        int curCharLen = 0;
        std::string curChar;

        std::string::const_iterator it = getText().begin();
        std::string::const_iterator end = getText().end();


        //decrement column so that the lowest is -1
        column--;
        if(textRows.size() == 0 || (column == -1 && row == 0))
        {
            //not in the text
            return -1;
        }
0.01s       for(size_t i = 0; i < textRows.size(); ++i)
        {
            //get length of row
0.00s           rowLen = _unicodeFunctions.getUtf8StringLength(textRows[i]);

            //handle -1th case

            //get next character
            do 
            {
0.00s               curCharLen = _unicodeFunctions.bringToNextUnichar(it,end);
0.01s               curChar = getText().substr(bytesSkipped,curCharLen);
                bytesSkipped += curCharLen;
                if(includeUnwantedChars)
                    retIndex++;
            } while (curChar[0] >= 0 && curChar[0] < ' ' && curChar != "\n");

            if(!includeUnwantedChars)
            retIndex++;

            //only increase for newlines
0.00s           if(curChar != "\n")
            {
                bytesSkipped -= curCharLen;
                retIndex--;
                it -= curCharLen;
            }

            if((int)i == row && column == -1)
            {
                return retIndex;
            }


0.06s           for(size_t j = 0; j < rowLen; ++j)
            {
                //get next character
                do 
                {
0.10s                   curCharLen = _unicodeFunctions.bringToNextUnichar(it,end);
0.91s                   curChar = getText().substr(bytesSkipped,curCharLen);
0.03s                   bytesSkipped += curCharLen;

0.03s                   if(includeUnwantedChars)
                        retIndex++;

0.11s               } while (curChar[0] >= 0 && curChar[0] < ' ' && curChar != "\n");

0.06s               if(!includeUnwantedChars)
0.00s                   retIndex++;

0.02s               if((int)i == row && (int)j == column)
                {
                    return retIndex;
                }
            }
        }

        return retIndex;
    }

Как я могу оптимизировать это?

Спасибо

Что делает @Erikимеется в виду про двойную очередь из символов?

1 Ответ

1 голос
/ 16 марта 2011

Вы извлекаете подстроку с помощью:

curChar = getText().substr(bytesSkipped,curCharLen);

Но тогда вы используете только первый элемент. Вы можете избежать построения / копирования строк, просто извлекая нужную char.

На общую алгоритмическую оптимизацию - я бы потратил ресурсы, необходимые для создания deque символьных объектов вместо использования std::string. Это позволит вам напрямую индексировать любой символ, не нужно сканировать и анализировать одни и те же последовательности utf-8 снова и снова.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...