Главная страница
    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.49 MB
Время: 0.038 c
3-1089294262
Falendysh
2004-07-08 17:44
2004.08.01
Проблема с Blob --> Jpeg


8-1084885435
Iraizor
2004-05-18 17:03
2004.08.01
ошибка после завершения приложения работающего с канвой


1-1089974539
Саша
2004-07-16 14:42
2004.08.01
Печать компонента: StringGrid


3-1089270297
Koala
2004-07-08 11:04
2004.08.01
Вопрос мастерам


9-1082292368
Шлац
2004-04-18 16:46
2004.08.01
Принадлежность точки грани





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский