Вверх ↑
Этот топик читают: Гость
Ответов: 9906
Рейтинг: 351
#31: 2017-09-02 20:57:47 ЛС | профиль | цитата
Galkov писал(а):
Если будут заметные улучшения -- обязательно сообщу.

Да, получилось. Сканирование по памяти (а-ля в Str_Enum) гораздо быстрее системных заморочек в TStream.ReadStr
Такая схема:
Add(Hub,2606912,154,126)
{
OutCount=4
link(onEvent1,1727045:doReset,[(235,132)(235,41)])
link(onEvent2,6449920:doClear,[])
link(onEvent3,12437222:doOpen,[(291,146)(291,181)])
link(onEvent4,12675296:doRepeat,[(179,153)(179,34)])
}
Add(SharedStream,12437222,301,175)
{
PageMem=260
Point(FileSize)
Point(FileOffset)
link(Offset,6449920:Result,[])
AddHint(44,6,33,13,PageMem)
}
Add(Math,6449920,315,126)
{
Point(doClear)
link(onResult,13850635:doCalc,[])
link(Op1,12437222:FileOffset,[(321,117)(356,117)(356,215)(335,215)])
}
Add(Button,2506679,56,126)
{
Left=14
Top=21
Width=90
Caption="Open Multicopy"
link(onClick,9843132:doExecute,[])
}
Add(ProgressBar,9114966,532,189)
{
Left=124
Top=21
Width=483
Ctl3D=0
ProgressColor=-16777203
}
Add(MathParse,13850635,371,126)
{
MathStr="%2 * 100 / %1"
link(onResult,9701619:doCompare,[])
link(X1,12437222:FileSize,[(377,117)(363,117)(363,222)(328,222)])
}
Add(Hub,15947962,483,133)
{
OutCount=4
link(onEvent1,12592788:doProcessMessages,[(508,139)(508,97)])
link(onEvent2,6300424:doOperation,[])
link(onEvent3,9114966:doPosition,[(515,153)(515,195)])
link(onEvent4,12437222:doRemapping,[(508,160)(508,230)(291,230)(291,188)])
}
Add(ODialog,9843132,105,126)
{
link(onExecute,2606912:doEvent1,[])
}
Add(Application,12592788,532,91)
{
Wait=1
Point(onTerminate)
link(onTerminate,9119129:doWork2,[(571,97)(571,83)])
}
Add(Repeat,12675296,196,28)
{
link(onRepeat,1727045:doScan,[])
}
Add(LineBreakEx,7154492,315,28)
{
Caption="Enum_Lines"
}
Add(MainForm,5675648,581,140)
{
Left=20
Top=105
Width=641
Height=107
Caption="FileMapVewer"
Position=1
Point(onClose)
}
Add(Math,6300424,532,140)
{
OpType=35
Op2=0.01
link(onResult,5675648:doCaption,[])
}
Add(If_else,9701619,420,126)
{
Type=4
Op2=Real(100)
link(onTrue,9119129:doWork3,[(466,132)])
link(onFalse,15947962:doEvent1,[])
}
Add(HubEx,9119129,462,77)
{
Angle=2
link(onEvent,12675296:doStop,[(186,83)(186,41)])
}
Add(InlineCode,1727045,259,28)
{
WorkPoints=#58:doScan=Сканирование текстовых строк в памяти Stream.Memory|37:doReset=Обнуление начального смещения|39:doStop=Остановка потока событий onLines|
EventPoints=#29:onLines=Поток текстовых строк|69:onNext=Выход строки за границу BlockSize (и выдает BlockSize в поток)|
VarPoints=#65:Position=Смещение конца прочитанной строки в памяти Stream.Memory|
DataPoints=#68:Stream=Данные типа MemoryStream для сканирования, читаемые по doScan|
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|21:uses kol,Share,Debug;|0:|4:type|29: THiAsmClass = class(TDebug)|11: private|22: Start,PTR:PChar;|21: Offset:integer;|19: stop:boolean;|10: public|38: onLines,onNext,Stream:THI_Event;|49: procedure doScan (var dt:TData; idx:word);|49: procedure doReset (var dt:TData; idx:word);|49: procedure doStop (var dt:TData; idx:word);|49: procedure Position(var dt:TData; idx:word);|6: end;|0:|14:implementation|0:|16:uses hiStr_Enum;|0:|55:const BlockSize = $100000; // 1M - граница сканирования|0:|29:procedure THiAsmClass.doScan;|27:var st:PStream; sz:integer;|5:begin|33: st := ReadStream(dt,Stream);|21: Start := st.Memory;|19: sz := st.Size;|26: PTR := Start + Offset;|17: stop := false;|53: while (Offset < BlockSize)and(Offset < sz) do begin|57: _hi_onEvent(onLines, SFParse(PTR, #13, sz - Offset));|32: if PTR^ = #10 then inc(PTR);|26: Offset := PTR - Start;|23: if stop then break;|6: end;|24: dec(Offset,BlockSize);|42: _hi_CreateEvent(dt, @onNext, BlockSize);|4:end;|0:|30:procedure THiAsmClass.doReset;|5:begin|14: Offset := 0;|4:end;|0:|29:procedure THiAsmClass.doStop;|5:begin|15: stop := true;|4:end;|0:|31:procedure THiAsmClass.Position;|5:begin|29: dtInteger(dt, PTR - Start);|4:end;|0:|4:end.|
link(onLines,7154492:doWork,[])
link(onNext,6449920:doOperation,[(298,41)(298,132)])
link(Stream,12437222:Stream,[(265,19)(272,19)(272,215)(307,215)])
}
сканирует мой тестовый файл (4181 копию KOL-а) за пару минут.
Это как бы минимальный вариант, без обработки строк.
У меня есть тест "на отсутствие левых строк".
Это примерно такая добавка к схеме ((там CounterEx в несколько странном режиме - перед Repeat.doRepeat необходимо ему установить -1 через doValue, или просто doReset; к точкам Srt2 и Str3 для FormatStr я подключал SharedStream.FileOffset и InlineCode.Position; а от Message.onNO делал остановки обоих циклов)):
Add(Button,791114,56,259)
{
Left=14
Top=42
Width=90
Caption="Open Original"
link(onClick,9992502:doExecute,[])
}
Add(LineBreakEx,9345278,56,308)
{
Caption="Enum_Lines"
Type=1
link(OnEvent,13126142:doEvent1,[])
}
Add(ODialog,9992502,105,259)
{
link(onExecute,3553401:doLoad,[(235,265)(235,286)])
}
Add(StrList,3553401,245,252)
{
Point(doLoad)
Point(doGetString)
Point(String)
}
Add(Message,11988565,371,315)
{
Caption="Error"
Type=2
Icon=3
Point(onNO)
}
Add(FormatStr,2267811,322,315)
{
DataCount=3
Mask="Строка <%1> не найдена в оригинале\r\nСмещение в мультикопии <%2 + %3>\r\n\r\nПродолжить ?"
link(onFString,11988565:doMessage,[])
}
Add(CounterEx,9973065,196,287)
{
Max=64290
Direct=1
Point(doReset)
Point(doValue)
Point(doPrev)
link(onNext,3553401:doGetString,[])
}
Add(If_else,12879812,259,315)
{
Type=5
link(onTrue,2267811:doString,[])
link(Op2,3553401:String,[])
}
Add(Hub,13126142,154,308)
{
link(onEvent1,9973065:doPrev,[])
link(onEvent2,12879812:doCompare,[])
}
- которая шелестит уже 10 минут
Все равно, побыстрее, чем раньше.
И совершенно понятно, что это уже время на обработку строк (а не на их парсинг).
А раньше (~70 минут) - это было время именно на парсинг (что не очень правильно).

Редактировалось 8 раз(а), последний 2017-09-03 08:04:47
карма: 9

0
31
Сообщение
...
Прикрепленные файлы
(файлы не залиты)