![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
![]() Добрый день. Есть функция удаления подстроки типа <gg hhh>jjjj</gg> из строки
(на самом деле посимвольное копирование когда это не запрещено условием) Код:
function DelUseless(const Data:string):string; var Len,I,EndTeg,Differ,J:integer; DefineTeg:string; (*первые N символов после <*) begin Len:=Length(Data); SetLength(Result, Len); Differ:=0; J:=0; if Length(Data) = 0 then Exit else for I := 1 to Length(Data) do (*-----------------ЦИКЛ-----------------------------*) begin if Differ > 0 then Dec(Differ) else if (Data[i] = '<') then begin DefineTeg:=Copy(Data, I,10); (*тут тормоз?*) if (PosEx('<script', DefineTeg,1)= 0) then begin Inc(J); Result[J]:=Data[i]; end else begin EndTeg:=PosEx('</script>',Data,I); if (EndTeg > 0) then Differ:=(EndTeg - I + 8); end end else begin Inc(J); Result[J]:=Data[i]; end end; (*-----------------конец-----------------------------*) SetLength(Result, J); end; (*все работает*) функция работает достаточно быстро (файл 3 мб за 30 мС обрабатывает) но есть подозрение, что использование COPY (DefineTeg:=Copy(Data, I,10) ![]() Внимание!! Вопрос: 1. действительно ли COPY не самое лучшее решение по быстродействию 2. чем можно заменить COPY? может вставка на ASM? |
#2
|
|||
|
|||
![]() а разве Copy уже не написана на асме?
не заморачивайся) 30мсек |
#3
|
||||
|
||||
![]() Вообще не понимаю использования PosEx для сравнения строк.
jmp $ ; Happy End! The Cake Is A Lie. |
#4
|
||||
|
||||
![]() тут проблема не в Copy, а в алгоритме.
Пишу программы за еду. __________________ |
#5
|
|||
|
|||
![]() Цитата:
если можно поподробнее. ведь в букваре сказано: функция для поиска в строке, именуемая PosEx. |
#6
|
||||
|
||||
![]() Зачем искать в строке, когда можно просто сравнить строки на равенство? Копировать не 10 символов, а 7 (длина строки "<script"), а затем сравнить копированную строку со "<script" обычным "равно".
Вообще NumLock прав. Не понимаю этих плясок с бубном вокруг цикла for, когда гораздо быстрее было бы сделать while, на котором лишние итерации можно просто пропустить. jmp $ ; Happy End! The Cake Is A Lie. |
#7
|
|||
|
|||
![]() тут все немножко сложнее, сейчас функция уже имеет вид
Код:
function DelUseless(const Data:string):string; const Teg1 = '<script'; Teg2 = '<style'; Teg3 = '<noscript'; Teg4 = '<applet'; Teg5 = '<object'; Teg6 = '<textarea'; Teg7 = '<audio'; Teg8 = '<button'; Teg9 = '<canvas'; Teg10 = '<comment'; Teg11 = '<datalist'; Teg12 = '<del'; Teg13 = '<meter'; Teg14 = '<noembed'; Teg15 = '<optgroup'; Teg16 = '<output'; Teg17 = '<progress'; var Len,I,EndTeg,Differ,J:integer; DefineTeg:string; (*первые N символов после <*) Pos1,Pos2:integer; Pattern:string; starttime,endtime,q:int64; begin starttime:=GetTickCount; Len:=Length(Data); SetLength(Result, Len); Differ:=0; J:=0; if Length(Data) = 0 then Exit else for I := 1 to Length(Data) do (*-----------------ЦИКЛ-----------------------------*) begin (*2 Cycle*) if Differ > 0 then Dec(Differ) else if Data[i] <> '<' then begin Inc(J); Result[J]:=Data[i]; (**) end else begin DefineTeg:=Copy(Data, I,11); (*копируем 12 символов*) Pos1:=PosEx(' ',DefineTeg,1); (*позиция первого пробела *) if Pos1 = 0 then (*если пробела нет ищем >*) Pos1:=PosEx('>',DefineTeg,1); (*позиция первого >*) Pos2:=Pos1-1; Pattern:=Copy(DefineTeg, 1, Pos2); (*выделяем паттерн тега*) (*----выбор тега на CASE------------------------*) case AnsiIndexStr(Pattern, [Teg1, Teg2, Teg3, Teg4, Teg5, Teg6, Teg7, Teg8, Teg9, Teg10, Teg11, Teg12, Teg13, Teg14, Teg15, Teg16, Teg17]) of 0:begin EndTeg:=PosEx('</script>',Data,I); if (EndTeg > 0) then Differ:=(EndTeg - I + 8); end; 1:begin EndTeg:=PosEx('</style>',Data,I); if (EndTeg > 0) then Differ:=(EndTeg - I + 7); end; 2:begin EndTeg:=PosEx('</noscript>',Data,I); if (EndTeg > 0) then Differ:=(EndTeg - I + 10); end; 3:begin EndTeg:=PosEx('</applet>',Data,I); if (EndTeg > 0) then Differ:=(EndTeg - I + 10); end; 4:begin EndTeg:=PosEx('</object>',Data,I); if (EndTeg > 0) then Differ:=(EndTeg - I + 10); end; 5:begin EndTeg:=PosEx('</textarea>',Data,I); if (EndTeg > 0) then Differ:=(EndTeg - I + 10); end; 6:begin EndTeg:=PosEx('</audio>',Data,I); if (EndTeg > 0) then Differ:=(EndTeg - I + 10); end; 7:begin EndTeg:=PosEx('</button>',Data,I); if (EndTeg > 0) then Differ:=(EndTeg - I + 10); end; 8:begin EndTeg:=PosEx('</canvas>',Data,I); if (EndTeg > 0) then Differ:=(EndTeg - I + 10); end; 9:begin EndTeg:=PosEx('</comment>',Data,I); if (EndTeg > 0) then Differ:=(EndTeg - I + 10); end; 10:begin EndTeg:=PosEx('</datalist>',Data,I); if (EndTeg > 0) then Differ:=(EndTeg - I + 10); end; 11:begin EndTeg:=PosEx('</del>',Data,I); if (EndTeg > 0) then Differ:=(EndTeg - I + 10); end; 12:begin EndTeg:=PosEx('</meter>',Data,I); if (EndTeg > 0) then Differ:=(EndTeg - I + 10); end; 13:begin EndTeg:=PosEx('</noembed>',Data,I); if (EndTeg > 0) then Differ:=(EndTeg - I + 10); end; 14:begin EndTeg:=PosEx('</optgroup>',Data,I); if (EndTeg > 0) then Differ:=(EndTeg - I + 10); end; 15:begin EndTeg:=PosEx('</output>',Data,I); if (EndTeg > 0) then Differ:=(EndTeg - I + 10); end; 16:begin EndTeg:=PosEx('</progress>',Data,I); if (EndTeg > 0) then Differ:=(EndTeg - I + 10); end; else begin Inc(J); Result[J]:=Data[i]; end; (*------конец CASE------------------------------*) end; end; end; (*-------конец Цикла-------------------------------------*) SetLength(Result, J); endtime:=GetTickCount; q:=endtime-starttime; ShowMessage('TIME = '+IntToStr(q)); end; (*78(три тега) полная набор тегов 218 мС для 3 мб текста*) вот как тут ускорить обработку? может кто подскажет? |