![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Быстрое чтение файла [D5, Win95/98]
Кастуся © (2004-06-21 22:46:00)мастера, хелп!
обрабатываю файл "дедовским" методом: построчно читаю данные и со строкой делаю все необходимое.
Но не устраивает скорость. На P-I-133 файл в обрабатывает за . Можно ли увеличить скорость на стадии чтения? (Обработка прочитанной строки оптимизированна до максимума) Я знаю, использовать либо BlockRead либо TFileStream но там надо читать буферами, для этого надо знать где строка заканчивается. А можно как-нибудь построчно читать?
Хотел попробовать сл. код:
Start := Stream.Position;
End := Start;
Repeat
Stream.Read(Buffer^, 1024);
CRPos := FindCR(Buffer^); { где FindCR возвращает 0..1023 для CR,
и 1024, если он не найден}
Inc(End, CRPos);
Until CRPos < 1024;
GetMem(MyPChar, End - Start); { Здесь может быть +-1 -- мне лень сегодня проверять! }
Stream.Seek(Start);
Stream.Read(MyPChar^, End - Start)
но что такое FindCR?
В общем как тут быть. Дело срочное, хелп плиз!!!
Sandman25 (2004-06-23 16:03:00) [61]LastDelimiter(HexSt,w0)=32
эквивалентно
(Length(w0)=32) and (w0[32] in ['0'..'9','a'..'f'])
Кастуся (2004-06-23 15:47:00) [62]Sandman25 © (23.06.04 12:39) [22]
знац-ца так
AnsiLowerCase отключил
Это repeat
inc(k);
REAPage.Matr[i,k]:=w0[k];
until (k=32);
заменил на 1 команду CopyMemory вот как:
MoveMemory(@REAPage.Matr[i],@w0[1],32);
Скорость впечатляет: файл в 23.8Мб обрабатывает за 46 сек, когда до изменений было 56! Это на моем-то Celerone-533+SDRam-64Mb, а для кого это делается вообще P-I-133 + SD-RAM 16Mb! Так что там разница будет раза в 2 больше. Хотя там такие большие файлы не обрабатывают Макс - ~5Мб
HexSt:='0'+'1'+'2'+'3'+'4'+'5'+'6'+'7'+'8'+'9'+'a'+'b'+'c'+'d'+'e'+'f';
w0:=DelSpaces(W);
Bad:=(Length(w0)<>32);
if not Bad then Bad:=not (LastDelimiter(HexSt,w0)=32);
Sandman25 (2004-06-23 12:39:00) [63]>а так можно как-нибудь увеличить скорость ?
Не использовать Trim, DelSpaces, LastDelimiter, AnsiLowerCase
Это repeat
inc(k);
REAPage.Matr[i,k]:=w0[k];
until (k=32);
заменить на 1 команду CopyMemory
Кастуся (2004-06-23 12:33:00) [64]а так можно как-нибудь увеличить скорость ?
Anatoly Podgoretsky (2004-06-23 11:31:00) [65]Кастуся (23.06.04 09:08) [19]
Функции и так в памяти, всегда, Дельфи не интерпритатор.
Кастуся (2004-06-23 09:08:00) [66]короче вот что я тет выяснил
путаю я вас тут
львиную долю времени загрузки файла как раз занимет его одновременная обработка!
Может можно как-то подгружать функции в память, чтобы их быстрее вызывать? Вот может посмотрите как можно вот этот код оптимизировать:
AssignFile(F,FileName);
SetTextBuf(f,buf);
Reset(f);
Ln:=FileSize(F);
while not eof(F) do
begin
Readln(F,w);
if Trim(w)='TC' then
begin
Readln(F,W);
rst:=DelSpaces(W);
I:=0;
repeat
inc(i);
Readln(F,W);
w0:=DelSpaces(W);
Bad:=(Length(w0)<>32);
if not Bad then
Bad:=not (LastDelimiter(HexSt,AnsiLowerCase(w0))=32);
k:=0;
if not Bad then
repeat
inc(k);
REAPage.Matr[i,k]:=w0[k];
until (k=32);
until (i=8) or Bad;
if not Bad then
begin
if not Result then Result:=True;
Inc(DataTables[0].CurLen);
for I:=1 to MaxCol do
SetLength(DataTables[0].DataArr[I],DataTables[0].CurLen);
REAInfo.REAPage.ProcessMatr(rst);
end;
end;
Cps:=FilePos(F);
if Ln=0 then MainForm.StBar.Panels.Items[2].GaugeAttrs.Position:=100
else MainForm.StBar.Panels.Items[2].GaugeAttrs.Position:=Round((Cps/Ln)*100);
end;
MainForm.StBar.Panels.Items[1].Text:='';
CloseFile(F);
Jeer (2004-06-22 19:33:00) [67]Который в процессоре и ближе к нему чем к ОЗУ.
GrayFace (2004-06-22 19:20:00) [68]А что такое кэш первого уровня?
Serginio666 (2004-06-22 19:13:00) [69]>>GrayFace ©
Немного ошибаешься. Лучше грузить в блок соизмеримый с размером кэша первого уровня. В отличие от твоего способа, все данные будут лежать в кэше и проход по ним будет быстрее. Что и доказывают тесты в Serginio666 (22.06.04 14:10) [7]
GrayFace (2004-06-22 18:37:00) [70]Искать строку в файле действительно лучше не дедовским способом. Если файл меньше 50 MB (для малых оперативок еще меньше), то можно грузить весь в строку(FileRead или BlockRead) и искать в ней стандартными способами. Если файл огромен, то прийдется немного помучаться.
panov (2004-06-22 18:31:00) [71]>Кастуся (22.06.04 18:25) [12]
Серьезно.
Amoeba (2004-06-22 18:31:00) [72]
> Кастуся (22.06.04 18:25) [12]
> серьезно?
Совершенно серьезно.
Кастуся (2004-06-22 18:25:00) [73]серьезно?
Anatoly Podgoretsky (2004-06-22 17:59:00) [74]Не сортированый список, только перебором
Кастуся (2004-06-22 17:55:00) [75]Понимете, вся штука вот в чем: в текстовом файле находится строка-идентификатор, после чего ещё пару строк считывается и они обрабатываются. Т.е. вся фишка в том, чтобы как можно быстрее найти эту заветную строку. Таких блоков может быть много в файле.
Вот смотрел ещё:
http://delphiworld.narod.ru/base/search_text_in_text_file.html
но не могу разобраться. может подскажите?
Mim1 (2004-06-22 17:38:00) [76]
> [8] BFG9k (22.06.04 14:45)
> Паскаль в гробу перевернется после всего этого. CreateFile,SetFilePointer,FileRead,FileWrite,CloseHandle
> . API функции - лучший друг Delphi-программиста.
Ну ну :), я бы сказал лучший враг. Но это субьективно.
Если смотрите в будующее о api лучше забыть.
API приходят и уходят, ЯП остается :)
BFG9k (2004-06-22 14:45:00) [77]Паскаль в гробу перевернется после всего этого. CreateFile,SetFilePointer,FileRead,FileWrite,CloseHandle . API функции - лучший друг Delphi-программиста.
Serginio666 (2004-06-22 14:10:00) [78]Посмотри
http://www.1c.hippo.ru/cgi-bin/predownl.cgi?id=2019
Тест на чтения текстовых файлов различными способами. Также исходники объектов для последовательного чтения текстовых файлов
как в прямом так и в обратном направлении TTextReader и TTextBackReader использующие кольцевой буффер размером 64 кб с ограничением на длину строки 64 кб - 3 байта.
Кастуся (2004-06-22 09:44:00) [79]С TStringLIst я пробовал - медленнее чем просто readln Использую SetTextBuf Я думаю это помогает?
Anatoly Podgoretsky (2004-06-22 08:50:00) [80]Кастуся (22.06.04 08:40) [4]
Выигрываешь немного в скорости чтения, проигрываешь в обработке, придется самому разбирать буфер на строки и не дай бог на составляющии. Текстовые файлы обеспечивают отличный механизм разборки файла и преобразования из буквочек в типы. Но всему свое место, твоя задача нам неизвестна.
Могу предложить, если у тебя текстовый файл, то загнать его целиком в строковую переменную и ее присвоить TStringList.Text возможно это будет быстрее, а то и сразу загрузить в TStringList, по скорости можно выиграть немного, по сравнению с текстовыми файлам, но за счет проигрыша по памяти. Но это хорошо только для текста.