Форум: "KOL";
Текущий архив: 2005.01.02;
Скачать: [xml.tar.bz2];
ВнизDeleteStr & PChar Найти похожие ветки
← →
nice (2004-05-11 09:19) [0]Народ подскажите, а то уже четвертый день борюсь.
Пишу парсер, и когда дело доходит до файлов >400KB с частым вхождением удаляемой/заменяемой строки, моя процедура работает оочень медленно~15сек.
До этого использовал string, но система вообще не выносимо тормозила, перевёл проект на PChar, но работал с ним мало :( посмотрите, что ни так в процедуре(может по pchar статейки какие есть):
procedure DeleteStr(var src:PChar;const DelStr:PChar);
var
posInStr,lenText,lenDelSTR:dword;
strTemp:PChar;
begin
lenText:=StrLen(src);lenDelSTR:=StrLen(DelStr);GetMem(strTemp,lenText);
posInStr:=StrPosInt(StrLower(src),DelStr);// Поиск первого вхождения
while posInStr>0 do begin // разбиваем строку
lenText:=StrLen(src);
strCopy(strTemp,@src[posInStr]);
src[posInStr-lenDelSTR]:=#0; // обрезаем оригинал
StrLCat(src,strTemp,lenText); // складываем
posInStr:=StrPosInt(StrLower(src),DelStr);// Поиск следующего вхождения
if posInStr>=lenText then break;
end;
Freemem(strTemp);
end;
StrPosInt -это аналог strPos на ассемблере, только заставил возвращать положение в строке, может зря?
← →
SPeller © (2004-05-11 11:07) [1]Для ускорения работы со строками и прочими частыми выделениями небольших блоков памяти можно надо подключить стандартный дельфийский менеджер памяти. Для этого можно сделать отдельный юнит, в его разделе initialization прописать функцию UseDelphiMemoryManager и вставить этот юнит первым в разделе uses проекта. Можно, конечно, прописать вызов этой функции и в самом начале проекта перед любымидругими действиями.
← →
nice (2004-05-11 11:38) [2]SPeller ©
Вместо 31,8 -> 30.2sek.
Я просто пробовал в фаре этот же файл мучить, фар делает эту операцию мгновенно!
Причем не просто удаление а замену
← →
Bez (2004-05-11 12:43) [3]Вчера появилась проблема со событием OnResize
В этом событии пытался задавать положение элементов на форме, что бы, например, при изменении размеров кнопка находилась в нижнем правом углу и рядом сней еще одна кнопка...
Так вот, прога компилится нормально, но когда запускаешь ее на выполнение, то происходит ошибка.... (Access voilative....)
В VCL все было Ок.
Может кто что подскажет?
← →
Bez (2004-05-11 12:43) [4]извините, заглючило что то :(
← →
Delphi5.01 © (2004-05-11 16:25) [5]Vo eto slishkom lamerski poisk!
posInStr:=StrPosInt(StrLower(src),DelStr);// Поиск следующего вхождения
Podskaju StrPosInt kajdi raz s samogo nachala nachinaet poisk, a znachit esli str do 2mb to poluchaem chto dla nahojdenia poslednego simvola on doljen proitis po vsemu tekstu!!! Ludshe organizovivat for i:=1 to Length() do ili while do!
raznica gdeto 150 raz!!!! :-)))
← →
Delphi5.01 © (2004-05-11 16:28) [6]Vo eto slishkom lamerski poisk!
posInStr:=StrPosInt(StrLower(src),DelStr);// Поиск следующего вхождения
Podskaju StrPosInt kajdi raz s samogo nachala nachinaet poisk, a znachit esli str do 2mb to poluchaem chto dla nahojdenia poslednego simvola on doljen proitis po vsemu tekstu!!! Ludshe organizovivat for i:=1 to Length() do ili while do!
raznica gdeto 150 raz!!!! :-)))
Sorry za translit.
Da esli nujen bisti metod to, ia uje otvechal na etot vopros na forume est. Poishite poisk metobom hesha on daje bistrei for i:=1 to Length() do okolo 20 raz! Odnim slovom zdes nujni algoritmi bistrogo poiska a eto uje ne v etom forume eto nado zadachi po olimpiade iskat i ih reshenia!
Jelau udachi
sorry za translit!
← →
Delphi5.01 © (2004-05-11 16:35) [7]http://delphimaster.net/view/11-1080931846/
← →
nice (2004-05-11 16:55) [8]Delphi5.01 ©
Пасибо брат, вполне логично, буду переделывать.
← →
SPeller © (2004-05-12 02:48) [9]2 Delphi5.01
Начинай писать на русском, иначе твои посты на транслитерации будут удаляться.
← →
Viman © (2004-05-12 10:21) [10]Угу. Либо по-русский, либо natural english. А то этот псевдоиврит(псевдотранслит) очень тяжко читать... Тем более, что для транслита тоже есть свои правила.
← →
nice (2004-05-16 16:30) [11]Delphi5.01
проверил я твой метод хешей, работает он медленне чем простым прохождением по строке, может это на String верно, но на PChar точно проигрывает. Переписал несколько процедур на асм, производительность выросла на порядок, до тестю выложу на ftp если интересно кому.
← →
SPeller © (2004-05-16 17:33) [12]Во-во, не зря kol.pas в двух версиях идёт.
← →
nice (2004-05-16 21:30) [13]Хотел спросить как в асмовской подпрограмме выделить память для строки PChar?
Как правильно вызвать GetMem?
И можно использовать var?
function DeleteStr(src:PChar;strDel:PChar):PChar;assembler;
var
tempStr:PChar; ????????
← →
Vladimir Kladov (2004-05-16 21:45) [14]если хотите скорости, надо избавляться от выделения/освобождения памяти - это и есть основной тормоз при парсинге.
MOV EAX, size
CALL System.@GetMem
← →
nice (2004-05-16 21:50) [15]Ф-ия вернет в Eax указатель на выделенный диапазон?
У неё вроде 2 параметра...
У вас нет примерчика какого-нибудь???
← →
Gandalf © (2004-05-16 23:39) [16]KOL - один большой пример
← →
nice (2004-05-17 01:22) [17]Вот что я наклепал, работает 2,5сек на файле в 450Кб с частым вхождением :)
Для меня это большой прогресс.
Посмотрите пожайлуста, может я чего лишнего намудрил
function DeleteStrDoChar(const src,DelStr:PChar;const DoChar:Char):PChar;assembler;
asm
PUSH EAX
PUSH EDI
PUSH ECX
OR EAX,EAX // eax=src
JE @@BAD
OR EDX,EDX // edx=DelStr
JE @@BAD
PUSH EDX // edx v stek
MOV ESI,EAX // запомнили eax
XOR ECX,ECX // с нулевой позиции
CALL StrPos // делаем поиск
CMP EAX,-1
JZ @@NoStr // строка не найдена? прыжок
XOR EBX,EBX
@@nextPos:
CLD // очищаем флаг направления
ADD EAX,EBX
PUSH EAX // posStr
LEA EDI,[ESI+EAX] // EDi -> src[posStr]
PUSH ESI // запомнили src[0]
SUB ECX,EAX // ecx=кол-во итераций
MOV EAX,EDI
MOV dl,DoChar
CALL StrScan // Находим последний символ удаляемой подстроки
MOV ESI,EAX // <span..... !>!
INC ESI
REP MOVSB // Обрезали
POP EAX // Востановили src[0]
MOV ESI,EAX
POP ECX // Востановили счетчик
POP EDX // Востановили DelStr
PUSH EDX
MOV EBX,ECX
CALL StrPos // ищем очередное вхождение
CMP EAX,-1
jnz @@nextPos
@@NoStr:
POP EDX
@@BAD:
POP ECX
POP EDI
POP EAX
end;
← →
Yury Sidorov (2004-05-17 10:48) [18]Функции для работы с PChar начинают трормозить при длинных строках, т.к. эти функции сначала ищут конец строки, а потом делают свое действие. Для длинных строк лучше использовать свои функции, которые в одном цикле сразу проверяют конец строки и выполняют действие. Кстати, для обычных строк для определения длины строки никакого поиска делать не нужно. Функция Length() возвращает длину, записанную в заголовке строки. Исходя из этого, для поиска символа в строке максимально эффективно нужно определить длину строки через Length(), а потом делать поиск с помощью REPNE SCASB по буферу известной длины.
Страницы: 1 вся ветка
Форум: "KOL";
Текущий архив: 2005.01.02;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.038 c