Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.08.01;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.035 c
1-1089809469
Vanya
2004-07-14 16:51
2004.08.01
Фнукция вывода виндовского хинта при заполнении например едита


9-1082648653
AAA
2004-04-22 19:44
2004.08.01
Рекурсивное вычисление определителя матрицы.


6-1086005410
Ruwer, inc.
2004-05-31 16:10
2004.08.01
Как в indy HTTPServer вовремя обработать запрос и послать ответ.


3-1089000280
Алексей Петухов
2004-07-05 08:04
2004.08.01
Кодировка


14-1089951401
КаПиБаРа
2004-07-16 08:16
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
Английский Французский Немецкий Итальянский Португальский Русский Испанский