Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.08.22;
Скачать: CL | DM;

Вниз

Баг в StrScan   Найти похожие ветки 

 
VoX   (2004-03-12 01:46) [0]

С StrScan определенно что-то не так. Писал парсер и удивлялся почему он так медленно работает, хотя везде использую PChar и вообще все должно было работать на ура. Тогда уже стал замерять определенные участки кода вот такими вещами:
Time := GetTickCount;
 код
Inc(TimeSum, GetTickCount-Time);
и выяснил что бутылочным горлышком является как раз функция StrScan(). Причем замедление от нее было такое что парсинг с ней выполнялся у меня ~10 секунд, а после замены ее на паскальную версию из SysUtils время выполнения стало исчисляться десятками миллисекунд!


 
VoX   (2004-03-12 03:30) [1]

Хм, и еще заметил вещь непонятную.
Есть две процедуры: одна {1} - парсер работает много с PChar и глубокая рекурсия, вторая {2} - работа с MemStream, много записи в поток.
И вот замечена такая вещь: если отключена замена системных dcu, то {1} выполняется ~40мс, а {2} ~11 секунд! Если же включить замену, то {1} выполняется ~200мс, а {2} ~460 миллисекунд!!! Вот я не пойму откуда такая разница?! И ладно бы с заменой было бы медленней, ну там менеджер памяти может другой стоит, дак нет ведь {1} медленней, а {2} намного быстрей! Проект каждый раз я пересобираю (build), проверил уже несколько раз - история повторяется. Из-за чего такое может происходить?! Как такое объяснить?!
P.S. У меня Д7. Кстати, похоже что в замененных модулях для Д7 нету UseDelphiMemoryManager. А какой менеджер там стоит по умолчанию: дельфийский или свой какой-то и как его тогда поменять потому что на UseDelphiMemoryManager компилятор ругается.


 
VoX   (2004-03-12 03:50) [2]

Ай, пардон, насчет UseDelphiMemoryManager соврал, есть такой. Попробовал его и результат получился как уже выше описано с отключенными dcu! Как это можно объяснить? Все всегда кричат что наоборот в замененных библиотеках тормозной менеджер памяти, ан нет, получается что не всегда


 
Владимир Кладов   (2004-03-13 10:32) [3]

в замененных библиотеках по умолчанию работа начинается с упрощенного менеджера памяти, который весь состоит из 3 строк кода. Ясно, что он будет тормозить, т.к. не содержит никакой оптимизации. Для простых случаев этого достаточно. Вызов UseDelphiMemoryManager устанавливает тот менеджер памяти, который изначально сделан фирмой Borland - Inprise и оптимизирован для многократного выделения и освобождения мелких кусочков памяти, что и происходит при интенсивной работе с AnsiString. Но если НЕ ИСПОЛЬЗОВАТЬ AnsiString и переделать алгоритм так, чтобы работа шла исключительно с PChar, без постоянного выделения и освобождения памяти, то можно получить ускорение по сравнению с прежним алгоритмом в сотни раз, даже если использовался стандартный менеджер памяти.


 
Владимир Кладов   (2004-03-14 13:22) [4]

По оптимизации работы с потоками в памяти могу добавить: они тоже вообще не оптимизируются автоматически. Потому что для минимальных целей и так работает. Если надо оптимизировать, это очень просто: заранее укажите требуемый Size для потока. И тогда при записи по одному байту не будет происходить перевыделение памяти для всего потока. Другой вариант: перед записью проверять, что Position+AddedBytes<=Size, если это не так, перевыделить память: Size:=Size+N, где N - достаточно большое (например, 65536). Делается во многих местах и не хочется устраивать у себя такую проверку в каждом месте? Сделайте себе процедуру, и обращайтесь к ней. Например Write2Stream( Stream: PStream; var Buf; Size: Integer );
Вы программисты в общем, чего вас учить.


 
VoX   (2004-03-15 15:56) [5]

Ну а что насчет StrScan? Тут вне зависимости от менеджера памяти asm-версия из KOL работает намноого медленней чем pascal версия выдернутая из SysUtils


 
Владимир Кладов   (2004-03-15 18:59) [6]

а в исходники заглянуть - лень?

function StrScan(Str: PChar; Chr: Char): PChar; assembler;
asm
 {$IFDEF F_P}
 MOV   EAX, [Str]
 MOVZX EDX, [Chr]
 {$ENDIF}
       PUSH    EDI
       PUSH    EAX
       MOV     EDI,Str
       OR      ECX, -1
       XOR     AL,AL
       REPNE   SCASB
       NOT     ECX
       POP     EDI
       XCHG    EAX, EDX
       REPNE   SCASB

       XCHG    EAX, EDI
       POP     EDI

       JE      @@1
       XOR     EAX, EAX
       RET

@@1:    DEC     EAX
end {$IFDEF F_P} [ "EAX", "EDX", "ECX" ] {$ENDIF};

function StrScan(const Str: PChar; Chr: Char): PChar; assembler;
asm
       PUSH    EDI
       PUSH    EAX
       MOV     EDI,Str
       MOV     ECX,0FFFFFFFFH
       XOR     AL,AL
       REPNE   SCASB
       NOT     ECX
       POP     EDI
       MOV     AL,Chr
       REPNE   SCASB
       MOV     EAX,0
       JNE     @@1
       MOV     EAX,EDI
       DEC     EAX
@@1:    POP     EDI
end;

найдите 10 отличий


 
VoX   (2004-03-16 19:33) [7]

А я что не смотрел в исходники? Естественно смотрел. Сейчас попробовал обе эти функции и результат тот же самый. При использовании функций что дали вы, время выполнения ~12-13 секунд вне зависимости от исполльзования замены системных библиотек или нет. При использовании вот такой функции:
function StrScan(const Str: PChar; Chr: Char): PChar;
begin
 Result := Str;
 while Result^ <> Chr do
 begin
   if Result^ = #0 then
   begin
     Result := nil;
     Exit;
   end;
   Inc(Result);
 end;
end;
Без замены системных библиотек я получил 20мс!!!
И с заменой 231мс!
Почему получается что асм-версия работает настооолько медленней?


 
Yury Sidorov   (2004-03-17 00:29) [8]

Потому, что в ASM функции сначала ищется конец строки, а потом ищется нужный символ. Т. е. сканирование производится дважды, но быстро (REPNE   SCASB). На коротких строках это дает выигрыш. У тебя, наверное, строки очень длинные, поэтому предпочтительнее твой вариант. А еще лучше его аналог на асме.



Страницы: 1 вся ветка

Текущий архив: 2004.08.22;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.036 c
3-1091274506
Wolfram
2004-07-31 15:48
2004.08.22
Вопрос про ORDER BY


3-1090559510
korvin
2004-07-23 09:11
2004.08.22
Смена стандартных SYSDBA и masterkey


1-1092134649
Fath
2004-08-10 14:44
2004.08.22
MaskEdit


1-1091646763
Black-Grin
2004-08-04 23:12
2004.08.22
Combobox - редактирование


6-1087284001
HydraMarat
2004-06-15 11:20
2004.08.22
TIdTCPServer vs TTcpServer