Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Подскажите способ быстрой загрузки обычного текста [D5, Win2k]


Unknown user ©   (2004-07-13 17:51:00) 

При загрузке происходит разбивка на параграфы и копирование фрагмента загружаемого текста в строковую переменную, хранящую текст параграфа.


Fay   (2004-07-16 18:53:00) [1]


> Ну, вообщем спасибо, буду работать дальше.

Не за что. Просто хотелось размяться на стандартной задачке - я по ним уже скучаю. 8)

> Насколько я понимаю твой способ чтения даст выигрыш в скорости
> не только для текстовых файлов. Это так?

С любыми. То, что ты работаешь с "текстовыми" файлами - частность.

Удачи.


Unknown user   (2004-07-16 16:48:00) [2]

To Fay.

Попробовал твой способ, работает минимум в 5 раз быстрее. За, что и благодарю. В твоем коде осталась еще одна ошибка, и небольшая неточность -текст в параграф надо копировать с символом возврата каретки. Но исправить это было делом 3-х минут.
Но, почему такой выигрыш в скорости? Я думал совсем необязательно отображать файлы в память для того, чтобы повысить скорость чтения, ведь если файл небольшой Windows считывает его в память целиком (наверное, даже при использовании буфера чтения меньше размера файла). Или AnsiStrScan медленно работает?
Насколько я понимаю твой способ чтения даст выигрыш в скорости не только для текстовых файлов. Это так?
Ну, вообщем спасибо, буду работать дальше.


Fay   (2004-07-13 23:19:00) [3]

Я бы сказал несколько ошибочек 8)
if p2 = #13 then
 begin
   Par := TParagraph.Create(Self);
   Par.FFonts[0].EndChrInd := Length(Par.FText);
   FParagraphs.Add(Par);
   if p1 < p2 then
     SetString(Par.FText, PChar(p1), p2 - p1);
   Inc(p2);
   if p2 < pe then
     if p2^ = #10 then Inc(p2);
   p1 := p2;
 end
else
 Inc(p2);


Fay   (2004-07-13 23:10:00) [4]

При вечернем обходе найдена ошибочка 8)
...
if p2 <> pe then
 if p2 = #10 then Inc(p2);
p1 := p2 + 1;
...


Fay   (2004-07-13 22:51:00) [5]

М.б. не очень элегантно, но попробуй
var
 h, m, sz : Cardinal;
 v, p1, p2, pe : PChar;
begin
 h := CreateFile('c:\YourFile.ext', GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
 if h = INVALID_HANDLE_VALUE then Exit;
 try
   sz := GetFileSize(h, nil);
   if sz = 0 then Exit;
   m := CreateFileMapping(h, nil, PAGE_READONLY, 0, 0, 'BuBuBu');
   if m = 0 then Exit;
   v := MapViewOfFile(m, FILE_MAP_READ, 0, 0, 0);
   if v = nil then Exit;

   p1 := v;
   p2 := v;
   pe := p1 + sz - 1;

   while p2 <= pe do
     begin
       if p2 = #13 then
         begin
           Par := TParagraph.Create(Self);
           if p1 < p2 then
             SetString(Par.FText, PChar(p1), p2 - p1);
           if p2 <> pe then
             if p2 = #10 then Inc(p2);
           p1 := p2;
           Par.FFonts[0].EndChrInd := Length(Par.FText);
           FParagraphs.Add(Par);
         end;
       Inc(p2);
     end;
 finally
   if v <> nil then UnmapViewOfFile(v);
   if m <> 0 then CloseHandle(m);
 end;


Unknown user   (2004-07-13 21:00:00) [6]

To ASMiD.

Дело в том, что AnsiStrScan использует StrScan, а та в свою очередь написана на asm, значит должна работать быстрее, чем перебор символов в тексте по одному. А тип string в Делфи уже лет 10 не ограничен 255 символами (если конечно явно не указывать ShortString)


ASMiD   (2004-07-13 20:44:00) [7]

Ну очень мудрый код.
И как работать с S, если string-255 символов по максимуму.
В общем круто.
Попробуй все сделать в одном цикле с использованием if
for k1:=1 to Stream.Size-Stream.Position do begin
 if s[k1]=#10 then
и тд
end;


Unknown user   (2004-07-13 20:33:00) [8]

To Anatoly Podgoretsky. TSringList не устраивает, поскольку текст хранится в иной структуре, а использовать только для загрузки нецелесообразно.
Главная проблема даже не в загрузке текста непосредственно, а в поиске символа разделения абзацев, выделении памяти под абзац, копировании текста (смотрите код).


Unknown user   (2004-07-13 20:24:00) [9]

Показываю код.

function EndLinePos(ALine:PChar):integer;
var P:PChar;
begin
P:=AnsiStrScan(ALine,#13);
if P=nil
 then Result:=Length(ALine)
 else Result:=P-ALine+1;
end;

function LoadFromStream(Stream:TStream):boolean;
var Len,Start,Stop:integer;
   S:string;
   Par:TParagraph;
begin

Len:=Stream.Size-Stream.Position;
SetString(S,nil,Len);
Stream.Read(Pointer(S)^,Len);
Start:=1; S:=S+#13;
while Start<Len do begin
 Stop:=EndLinePos(PChar(@S[Start]))+Start;
 Par:=TParagraph.Create(Self);
 SetString(Par.FText,PChar(@S[Start]),Stop-Start);
 Par.FFonts[0].EndChrInd:=Length(Par.FText);
 FParagraphs.Add(Par);
 if S[Stop]=#10 then  Inc(Stop);
 Start:=Stop;
end; {while}

end;

Текст размером 800 кб и в несколько тысяч абзацев на Athlon 1600+ загружается 13 сек. Как оптимизировать?


Anatoly Podgoretsky   (2004-07-13 20:23:00) [10]

А использовать текстовые файлы Паскали или загрузку в TSringList не устраивает


ASMiD   (2004-07-13 19:53:00) [11]

Помоему для быстрого копирования ничего лучше Move(Sou,Dest,Siz) не придумали.


Reindeer Moss Eater   (2004-07-13 19:52:00) [12]

Это то, чего ты ищешь.


Unknown user   (2004-07-13 19:51:00) [13]

To Семен Сорокин. А что такое QuickLoad?


Fay   (2004-07-13 19:51:00) [14]

2Unknown user ©   (13.07.04 19:49) [4]
Покажите ВАШ код.


Unknown user   (2004-07-13 19:50:00) [15]

To Digitman. Параграф в смысле текстовый абзац.


Unknown user   (2004-07-13 19:49:00) [16]

To Reindeer Moss Eater
1. Из текстового файла.
2. В свой компонент (читай в память)

Тормозящие факторы:
1. Поиск символа #13 (конец абзаца)
2. Копирование фрагмента текста с текущей позиции до найденного символа #13 в строковую переменную, хранящую текст абзаца.


Семен Сорокин   (2004-07-13 18:03:00) [17]

2Unknown user
надо QuickLoad использовать


Digitman   (2004-07-13 17:54:00) [18]


> параграфа


"параграф" - определение достойно подробностей ? как думаешь ?


Reindeer Moss Eater   (2004-07-13 17:52:00) [19]

При загрузке происходит разбивка ...

При загрузке откуда?
При загрузке куда?


Наверх

Титульная страница Поиск, карта сайта Написать письмо