std string vs char производительность, лучшая техника для удаления частей с самого начала

ну, мне нужно обработать большой кусок текста, анализируя его линейно от начала до конца. И мне интересно, какой подход для этого лучше: использование char* или std::string. при использовании char* я могу изменить указатель на позицию дальше в строке, например.

//EDIT later: mallocing some space for text
char str[] = "text to analyse";
char * orig = str;
//process
str += processed_chars; //quite fast
//process again
// later: free(orig);

но с использованием строки мне, возможно, придется использовать std::string::erase - но он создает копию или перемещает байты или что-то в этом роде (я не знаю фактической реализации)

string str = "text to analyse";
//process
str = str.erase(0,processed_chars);

или есть способ изменить скрытый указатель std::string?

РЕДАКТИРОВАТЬ: поскольку Сильвен Дефрен запросил здесь больше кода:

class tag {
public:
    tag(char ** pch) {
        *pch = strstr(*pch,"<");
        if(pch == NULL) return;

        char *orig = *pch+1;
        *pch = strstr(*pch,">");
        if(pch == NULL) return;
        *pch+=sizeof(char); //moving behind the >

        //process inner tag data

        if(*(*pch-2)!='/'){// not selfclose
            while (!(**pch == '<' && *(*pch+1) == '/')){ //sarch for closing tag
                tag* kid = new tag(pch);
                sublings.push_back(*kid);
            }

            *pch = strstr(*pch,">");
            if(pch == NULL) return;
            *pch+=sizeof(char); //moving behind the >

            //add check if the clothing tag is matching

        }
    }
}

я использую его для рекурсивного разбора XML-подобной нотации

char str[] ="<father><kid /></fatherr>";
char * pch = str;
tag *root = new tag(&pch);

этот код чертовски уродлив, я только начинаю с низкоуровневой арифметики указателей и прочего, до сих пор использовал визуальные компоненты, так что не судите слишком строго


person Valerij    schedule 16.03.2011    source источник
comment
Пробовали ли вы профилировать оба подхода, чтобы увидеть, каково будет фактическое влияние?   -  person Mark Loeser    schedule 16.03.2011
comment
std::string str = анализируемый текст; char const * c = str.c_str() + 5;   -  person Erik    schedule 16.03.2011
comment
@Mark Loeser: при использовании erase алгоритм сопоставления становится суперлинейным (я думаю, O (n²).   -  person Fred Foo    schedule 16.03.2011
comment
Почему ты освобождаешь ориг? Это вызовет ошибку сегментации. Опечатка?   -  person MM.    schedule 16.03.2011
comment
Ты ничего не сделал malloc, почему ты звонишь free(orig)? Эта строка вызывает неопределенное поведение.   -  person fredoverflow    schedule 16.03.2011
comment
@MM, FredOverflow: опечатка, косые черты потеряны   -  person Valerij    schedule 16.03.2011


Ответы (3)


С std::string вы, вероятно, использовали бы std::string::iterator. Ваш код будет:

std::string str = "text to analyse";
std::string::iterator iter = str.begin();

// process
iter += processed_chars; 
person Sylvain Defresne    schedule 16.03.2011
comment
но как мне получить доступ к строке из моего iter и пойти дальше - это точка моей обработки и причина изменения указателя в версии char - person Valerij; 16.03.2011
comment
std::string::iterator в основном является замаскированным char* (или небольшой оберткой над ним). Чтобы прочитать текущий символ, разыменуйте его *iter, это вернет ссылку, чтобы вы могли записать в нее *iter = 'a'... - person Sylvain Defresne; 16.03.2011
comment
не совсем то, что я имею в виду, char foo[] = "lorem ipsum"; foo++; cout << foo; производит orem ipsum, и это то, что я хочу, так что заархивируйте здесь - person Valerij; 16.03.2011
comment
Вам придется сделать std::string foo = "lorem ipsum"; std::string::iterator it = foo.begin(); ++ it; std::cout << &*it;. - person Sylvain Defresne; 17.03.2011
comment
но как мне получить std::string оттуда - person Valerij; 18.03.2011
comment
Вы создаете новую строку std::string substring(iter, str.end());. - person Sylvain Defresne; 18.03.2011
comment
у меня есть только substr(size_t,size_t), и не создаст ли он копию? - person Valerij; 18.03.2011
comment
Да, это будет, но с char* вам также придется сделать копию в конце, если вы хотите ее вернуть (или вызывающему абоненту придется сохранить указатель на исходную строку и использовать его для освобождения памяти). Нам понадобится больше информации о том, какое использование вы хотите, чтобы действительно помочь вам выбрать то, что лучше. - person Sylvain Defresne; 19.03.2011

Все, что можно сделать с char*, можно сделать и с std::string::iterator.

person Benjamin Lindley    schedule 16.03.2011

Вы можете использовать std::string::iterator (см. здесь).

std::string в такой задаче не обязателен (но такие классы, как std::string, очень полезны в других ситуациях).

person artyom.stv    schedule 16.03.2011
comment
Учитывая, что std::string::iterator состоит из члена char* и пары встроенных функций, я уверен, что мы сможем ударить практически незаметно. :-) - person Bo Persson; 16.03.2011
comment
@Bo Persson: Но если вы решите создать метод nothrow? (если вы уверены, что не оставите выделенную память) std::string::iterator может кидать исключения (я думаю) (p.s. не уверен; чтобы уточнить это, нам нужно увидеть стандарт). - person artyom.stv; 16.03.2011
comment
Нет, итераторы не будут генерировать никаких исключений. Единственное исключение, которое вы получите, это bad_alloc при инициализации строки и нехватке памяти. - person Bo Persson; 16.03.2011
comment
@ Бо Перссон: Тогда ты прав :). Нет никакой разницы. - person artyom.stv; 16.03.2011