Przesunięcie wskaźnika początku łańcucha

0

Witajcie:)
Jest sobie łańcuch lanc o długości np. 10 MB. Chciałbym przeprowadzić na nim operację parsowania jakiegoś
parametru, który występuje w tym łańcuchu 1-2 tyś. razy pomiędzy tagiem początkowym a końcowym.
Zastosowałem poniższy mechanizm:

 While Pos(TagPoczatkowy, lanc)>0 do
 Begin
   lanc:=Copy(lanc, Pos(TagPoczatkowy, lanc)+length(TagPoczatkowy), length(lanc));
   Parametr:=Copy(lanc, 1, Pos(TagKoncowy, lanc)-1);
   Memo1.Lines.Add(Parametr);
   lanc:=Copy(lanc, Pos(TagKoncowy, lanc)+length(TagKoncowy), length(lanc));
 End;

Niestety jest dość mało wydajny, zapewne z powodu ciągłego kopiowania łańcucha od pierwszego znaku
występującego po tagu TagKoncowy do końca łańcucha (ostatni wiersz pętli), szczególnie na początkowym
etapie parsowania, kiedy łańcuch jest najdłuższy.

Pytanie: Czy jest sposób, żeby uniknąć tego kopiowania łańcucha, a tylko przesunać jego wskaźnik
początku na pozycję Pos(TagKoncowy, lanc)+length(TagKoncowy)? A może należałoby zastosować zupełnie
inny mechanizm?

0

MemoryStream + "ręczne" szukanie początku i końca

0
Misiekd napisał(a)

MemoryStream + "ręczne" szukanie początku i końca

A pod jakim względem będzie szybciej niż na stringu? W stringu to chociaż mam gotową i szybką funkcję Pos(..), a w strumieniu musiałbym szukać tagów początkowego/końcowego sprawdzając bajt po bajcie i jak trafię na pierwszy bajt tagu, to sprawdzać czy kolejne są zgodne z tagiem, a jeśli nie, to dalej jechać bajt po bajcie. Mi by chodziło bardziej o swego rodzaju truncate dla stringa, ale z lewej strony, żeby nie trzeba było przemieszczać w pamięci zawartości łańcucha.
No ale OK, sprawdzę na strumieniu, może pójdzie szybciej :)

0

gotową i szybką funkcję Pos

A co cię składania żeby nazwać ją szybką?

Ja bym potraktował stringa jako tablicę bajtów (ew. ręcznie alokowaną pamięć) i użył niezastąpionego move i CompareByte.

Mi by chodziło bardziej o swego rodzaju truncate dla stringa, ale z lewej strony

String nie ma ani lewej ani prawej strony. Generalnie to jeżeli chcesz się bawić w jakieś wysoce optymalizacyjne algorytmy, to zrezygnuj ze stringa którego obowiązują liczniki referencji itd. na rzecz Ręcznie przydzielanego obszaru pamięci którego możesz przycinać jak ci się żywnie podoba.

0
marogo napisał(a)

Pytanie: Czy jest sposób, żeby uniknąć tego kopiowania łańcucha, a tylko przesunać jego wskaźnik
początku na pozycję Pos(TagKoncowy, lanc)+length(TagKoncowy)?

Tak, jest. Można rozpoczynać kolejne poszukiwania od dowolnego miejsca łańcucha, niekoniecznie od początku.

PosEx

1 użytkowników online, w tym zalogowanych: 0, gości: 1