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

Вниз

Подскажите способ быстрой загрузки обычного текста   Найти похожие ветки 

 
Unknown user ©   (2004-07-13 17:51) [0]

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


 
Reindeer Moss Eater ©   (2004-07-13 17:52) [1]

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

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


 
Digitman ©   (2004-07-13 17:54) [2]


> параграфа


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


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

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


 
Unknown user ©   (2004-07-13 19:49) [4]

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

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


 
Unknown user ©   (2004-07-13 19:50) [5]

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


 
Fay ©   (2004-07-13 19:51) [6]

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


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

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


 
Reindeer Moss Eater ©   (2004-07-13 19:52) [8]

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


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

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


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

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


 
Unknown user ©   (2004-07-13 20:24) [11]

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

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 сек. Как оптимизировать?


 
Unknown user ©   (2004-07-13 20:33) [12]

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


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

Ну очень мудрый код.
И как работать с 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 21:00) [14]

To ASMiD.

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


 
Fay ©   (2004-07-13 22:51) [15]

М.б. не очень элегантно, но попробуй
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;


 
Fay ©   (2004-07-13 23:10) [16]

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


 
Fay ©   (2004-07-13 23:19) [17]

Я бы сказал несколько ошибочек 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);


 
Unknown user ©   (2004-07-16 16:48) [18]

To Fay.

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


 
Fay ©   (2004-07-16 18:53) [19]


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

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

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

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

Удачи.



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

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

Наверх




Память: 0.52 MB
Время: 0.064 c
1-1089966353
VAmpior$
2004-07-16 12:25
2004.08.01
Как засунуть. AVI в .exe или dll и потом его возпроизвести.


14-1089300168
Рома_ДЖ
2004-07-08 19:22
2004.08.01
Подскажите как можно защитить прогу. от размножения


3-1088762771
serg128
2004-07-02 14:06
2004.08.01
Как получить перечень параметров из запроса на PL SQL?


14-1089833539
Opilki_Inside
2004-07-14 23:32
2004.08.01
Могут ли студенты работать полный рабочий день?


3-1089169402
Jedu
2004-07-07 07:03
2004.08.01
DBGridEh - поля в записи?