Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.02.2013, 17:43   #1
Pcrepair
Форумчанин
 
Регистрация: 04.01.2011
Сообщений: 260
По умолчанию Функция COPY. Быстродействие.

Добрый день. Есть функция удаления подстроки типа <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?
Pcrepair вне форума Ответить с цитированием
Старый 16.02.2013, 17:51   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
может вставка на ASM?
Сору и так целиком на асме. Для чистоты эксперимента можешь попробовать move()
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 16.02.2013, 18:06   #3
Pcrepair
Форумчанин
 
Регистрация: 04.01.2011
Сообщений: 260
По умолчанию

заменил на
Код:
Move(Data[I],DefineTeg[1],10*SizeOf(Data[1]));
время то же самое. так что? оставить COPY? оно вроде попроще(магическая функция)
Pcrepair вне форума Ответить с цитированием
Старый 16.02.2013, 18:08   #4
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Берите из KOL функцию если вам так скорость нннада.
Человек_Борща вне форума Ответить с цитированием
Старый 16.02.2013, 18:09   #5
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Сору не только проще, но и надежнее. Я бы не парился по этому поводу.
Кстати я бы на твоем месте использовал StringReplace для удаления.
Или сочетание Pos() и delete()
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 18.02.2013, 07:35   #6
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

1. ЕСТЬ ОШИБКА
Проверять нужно не на '<script', а на '<script>'. Иначе вот это
1<script2</script>3 4<script>5</script>6
превратится в это
13 46
а должно вот в это
1<script2</script>3 46


2. ИСПОЛЬЗУЕМ ЦИКЛЫ ГРАМОТНО
Код:
function DelUseless2(const Data:string):string;
const
  BS = '<script>';
  ES = '</script>';
var
  Len,I,EndTeg,J:integer;
  DefineTeg:string;
  ch: Char;
begin
  Len:=Length(Data);
  if Len = 0 then Exit;
  SetLength(Result, Len);
  J:=0;
  I := 1;
  while I <= Len do begin
    ch := Data[I];
    if (ch = '<') then begin
      DefineTeg := Copy(Data, I,10);
      if PosEx (BS, DefineTeg,1) <> 0 then begin
        EndTeg := PosEx(ES,Data,I+7);
        if EndTeg <> 0 then begin
          I := EndTeg + 8;
        end
        else begin
          Inc(J);
          Result[J] := ch;
        end;
      end
      else begin
        Inc(J);
        Result[J] := ch;
      end;
    end
    else begin
      Inc(J);
      Result[J] := ch;
    end;
    Inc(I);
  end;
  SetLength(Result, J);
end;
на 20% быстрее

3. ХИТРОСТИ ПРИВЕДЕНИЯ ТИПОВ ВМЕСТО COPY
Нам не нужно само копирование в данном случае
Код:
function DelUseless3 (Data: string):string;
const
  BS = '<script>';
  ES = '</script>';
type
  Str8 = String[8];
  PStr8 = ^Str8;
var
  Len, I, J, EndTeg: Integer;
  s: Str8;
  ch: Char;
begin
  Len := Length(Data);
  if Len = 0 then Exit;
  SetLength (Result, Len);
  J := 0;
  I := 1;
  while I <= Len do begin
    ch := Data[I];
    if ch = '<' then begin
      s := PStr8(@Data[I-1])^;
      if s = BS then begin
        EndTeg := PosEx(ES, Data, I+7);
        if EndTeg <> 0 then begin
          I := EndTeg + 8;
        end
        else begin
          Inc(J);
          Result[J] := ch;
        end;
      end
      else begin
        Inc(J);
        Result[J] := ch;
      end;
    end
    else begin
      Inc(J);
      Result[J] := ch;
    end;
    Inc(I);
  end;
SetLength(Result, J);
end;
на 38% быстрее

4. СТРАННОЕ УПОРСТВО
Ведь вот это работает быстрее
Код:
function DelUselessMy (Data, BS, ES: String): String;
var
  o1, o2, i, s, d, L, LBS, LES: Integer;
begin
  L := Length (Data);
  if L = 0 then Exit;
  SetLength (Result, L);
  LBS := Length(BS);
  LES := Length(ES);
  o1 := 1;
  s := 1;
  d := 0;
  while True do begin
    o1 := PosEx(BS, Data, s);
    if o1 = 0 then Break
    else begin
      o2 := PosEx(ES, Data, o1+LBS);
      if o2 = 0 then Break
      else begin
        for i := s to o1-1 do
          Result[i-d] := Data[i];
        s := o2 + LES;
        d := d + (s - o1);
      end;
    end;
  end;
  for i := s to L do
    Result[i-d] := Data[i];
  SetLength (Result, L-d);
end;
на 75% быстрее при условии, что еще и задавать строки поиска можно

5. ХОТЯ МОЖЕТ И НЕ СТРАННОЕ или ХИТРОСТИ ПРИВЕДЕНИЯ ТИПОВ 2
Самый быстрый вариант, но только для постоянных строк поиска
Код:
function DelUseless4 (Data, BS, ES: String): String;
var
  BeginFlag: Boolean;
  Len, I, J, K, EndTag, LBS, LES: Integer;
  s: PChar;
  ch: Char;
begin
  Len := Length(Data);
  if Len = 0 then Exit;
  SetLength (Result, Len);
  LBS := Length(BS);
  LES := Length(ES);
  J := 0;
  I := 1;
  while I <= Len do begin
    ch := Data[I];
    if ch = '<' then begin
      s := PChar(@Data[I-1]);
      BeginFlag := True;
      for K:=1 to 8 do
        if s[K] <> BS[K] then begin
          BeginFlag := False;
          Break;
        end;
      if BeginFlag then begin
        EndTag := PosEx (ES, Data, I+8);
        if EndTag <> 0 then begin
          I := EndTag + 8;
        end
        else begin
          Inc(J);
          Result[J] := ch;
        end;
      end
      else begin
        Inc(J);
        Result[J] := ch;
      end;
    end
    else begin
      Inc(J);
      Result[J] := ch;
    end;
    Inc(I);
  end;
SetLength(Result, J);
end;
на 136% быстрее.

P.S.: Скорость проверял на Lazarus'е, потому может не соответствовать на Delphi. Но тенденция должна сохраниться.

Последний раз редактировалось Sibedir; 18.02.2013 в 12:02. Причина: Мамочки, скока ошибок сам наделал
Sibedir вне форума Ответить с цитированием
Старый 18.02.2013, 14:13   #7
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

Понравилась мне чёт эта тема
Вот 2 программки сравнивающие разные функции.
Удаление подстрок.zip
Во 2-ом варианте все ф-и имеют в качестве параметров тэги. А DelUseless3 вырождается. Дома гляну, как это на Delphi работает.
Sibedir вне форума Ответить с цитированием
Старый 18.02.2013, 16:54   #8
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

Цитата:
Проверять нужно не на '<script', а на '<script>'
Но и не '<script>', ведь у него же должны быть атрибуты ещё.
Somebody вне форума Ответить с цитированием
Старый 18.02.2013, 19:13   #9
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

Понял.
____________________
Sibedir вне форума Ответить с цитированием
Старый 19.02.2013, 20:49   #10
Pcrepair
Форумчанин
 
Регистрация: 04.01.2011
Сообщений: 260
По умолчанию

всем спасибо, скоро добавлю свой вариант
Pcrepair вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Быстродействие VBA Sasha_Smirnov Microsoft Office Word 24 06.12.2012 13:35
Быстродействие SQL и C# Manolla C# (си шарп) 3 28.09.2011 08:26
Быстродействие инструментов С++ coinkrsk Общие вопросы C/C++ 2 07.10.2010 13:34
Не работает функция copy и delete omigos99 Паскаль, Turbo Pascal, PascalABC.NET 2 03.10.2010 13:46
Быстродействие sxerox Паскаль, Turbo Pascal, PascalABC.NET 2 19.04.2010 18:53