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

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

Чтение из 2-х гигового лога...


Страницы:   1 2 3 4

Owa ©   (2008-02-04 23:24:00) 

Здравствуйте, хочу у вас поинтересоваться какой метод лучше применять для быстрого поиска в файле?

Лог сервера. Лог текстовой с кодировкой юникод.

Я использую вот что:


var
 BaseItem : string;
 F : textfile;
 STL: TStringList;
begin
if key = VK_return then
begin
STL := TStringList.Create;

AssignFile(F, FP);
reset(f);
try
 while not Eof(F) do
  begin
   Readln(F, BaseItem);
    If pos(pchar(AnsiLowerCase(Edit1.Text)), pchar(AnsiLowerCase(BaseItem))) <>0 then
       STL.Add(UTF8Decode(BaseItem));
       Application.ProcessMessages();
  end;

finally
 CloseFile(F);
end;

RichEdit1.Lines.Text := STL.Text;
Application.ProcessMessages();

STL.Free;
end;


При маленьком объеме файла результат получается давольно быстро. А когда произвожу поиск в файле размером больше 2 гигов то процесс длится очень и очень долго. Есть-ли какой-то более быстрый метод для поиска в файле?
Спасибо.


Slym   (2008-02-05 12:18:00) [41]

palva ©   (05.02.08 12:04) [31]
плохой тест... первое что бросилось - SetLength(s, 50000) - фиксированный буфер, а в первом варианте постоянно он пересоздается (ReadLn(fo, s);) а это утечка времени * 10млн - много


palva   (2008-02-05 12:16:00) [42]


> хам   (05.02.08 11:46) [25]
> > [23] palva ©   (05.02.08 11:46)
> > Может быть, вы надеетесь, что Windows будет буферизовать
> > и читать данные большими блоками?

> Я не надеюсь, я это точно знаю.

Ну значит, вы неправы. Как и в том, что называете буферизацию кэшированием.


palva   (2008-02-05 12:04:00) [43]


> пишешь тест, читая readln и большими кусками, хронометрируешь,
>  выкладываешь результаты вместе с кодом теста.

Заполнение большого файла 500000000 байт

{$APPTYPE CONSOLE}
var
 fo: textfile;
 i: Integer;
begin
 Assign(fo, 'bigtest.txt');
 Rewrite(fo);
 for i:=1 to 10000000 do
   WriteLn(fo, '012345678901234567890123456789012345678901234567');
 closefile(fo);
end.

Построчное чтение

{$APPTYPE CONSOLE}
uses SysUtils;
var
 fo: textfile;
 i: Integer;
 s: string;
begin
 WriteLn(TimeToStr(now));
 Assign(fo, 'bigtest.txt');
 Reset(fo);
 for i:=1 to 10000000 do begin
   ReadLn(fo, s);
   if pos(' ', s) > 0 then WriteLn('OK');
 end;
 closefile(fo);
 WriteLn(TimeToStr(now));
end.

11:42:18
11:42:45
27 секунд

Чтение большими блоками

{$APPTYPE CONSOLE}
uses SysUtils;
var
 fo: file;
 i: Integer;
 s: string;
begin
 WriteLn(TimeToStr(now));
 Assign(fo, 'bigtest.txt');
 Reset(fo, 50000);
 SetLength(s, 50000);
 for i:=1 to 10000 do begin
   BlockRead(fo, s[1], 1);
   if pos(' ', s) > 0 then WriteLn('OK');
 end;
 WriteLn(TimeToStr(now));
 closefile(fo);
end.

11:52:03
11:52:11
8 секунд


хам   (2008-02-05 11:53:00) [44]

> [27] ANB   (05.02.08 11:50)
> Попробовал фаром - файл 1 Гб, искал строку которой нет.
> Примерно 30 секунд.

1204/30 = 34 — примерно скорость линейного чтения современного жесткого диска.


хам   (2008-02-05 11:52:00) [45]

> [26] clickmaker ©   (05.02.08 11:48)
> для оптимального чтения размер блока должен быть кратен
> размеру кластера, т.е. минимум 512.

Есть юникодовые кодировки с нефиксированным размером символа.


хам   (2008-02-05 11:52:00) [46]

> [26] clickmaker ©   (05.02.08 11:48)
> для оптимального чтения размер блока должен быть кратен
> размеру кластера, т.е. минимум 512.

Есть юникодовые кодировки с нефиксированным размером символа.


ANB   (2008-02-05 11:50:00) [47]

Милин. Делфи то нету пока :(
Попробовал фаром - файл 1 Гб, искал строку которой нет. Примерно 30 секунд. Т.е. быстрый способ есть :)


clickmaker   (2008-02-05 11:48:00) [48]


> ЗЫ. Кстати, при чтении большими блоками есть грабля из за
> юникодовой кодировки. Т.е. мона умудрится прочитать токо
> один байт двухбайтного символа.

для оптимального чтения размер блока должен быть кратен размеру кластера, т.е. минимум 512. По крайней мере, не должен быть нечетным


хам   (2008-02-05 11:46:00) [49]

> [23] palva ©   (05.02.08 11:46)
> Может быть, вы надеетесь, что Windows будет буферизовать
> и читать данные большими блоками?

Я не надеюсь, я это точно знаю.


ANB   (2008-02-05 11:46:00) [50]


> хам   (05.02.08 11:41) [21]

Ща потестим . . .
ЗЫ. Кстати, при чтении большими блоками есть грабля из за юникодовой кодировки. Т.е. мона умудрится прочитать токо один байт двухбайтного символа.


palva   (2008-02-05 11:46:00) [51]

хам   (05.02.08 09:33) [11]
> Это уже забота виндового кеша, а он, поверь, с ней справляется.

Не понимаю о чем вы. Данные в сабже читаются однократно и не кэшируются. Может быть, вы надеетесь, что Windows будет буферизовать и читать данные большими блоками? Или компилятор делфи буферизует чтение данных? Ни то ни другое не происходит.
Вот если бы вы писали на си, вы действительно, не почувствовали бы особой разницы. В сишных библиотеках последовательный ввод данных буферизуется.


clickmaker   (2008-02-05 11:42:00) [52]


> Пользователю за раз никогда не понадобится больше 100кб
> информации в одном контролле.

не факт. Лично я сталкивался с ситуацией поиска в многометровом логе. Правда, я ничего для этого не писал, а юзал вьювер FAR'a )
В стандартные контролы только грузиться такой лог будет несколько минут (десятков секунд в лучшем случае)


хам   (2008-02-05 11:41:00) [53]

> [20] ANB   (05.02.08 11:39)
> реадлн - не самый шустрый способ прочитать файл.

Я тебе так скажу: Прочитать файл с диска — не самый шустрый способ прочитьтать файл. А уж через что он читается, без раницы, все равно чтение с диска медленне копирования в оперативной памяти.


хам   (2008-02-05 11:39:00) [54]

> [18] clickmaker ©   (05.02.08 11:36)
> RichEdit - плохой кандидат для 2-гиговых логов.

Любой компонент — любой кандидат для 2-гиговых логов. Пользователю за раз никогда не понадобится больше 100кб информации в одном контролле.


ANB   (2008-02-05 11:39:00) [55]


> Owa   (04.02.08 23:24)

1. Найти, что больше тормозит - чтение или поиск по строке.
Для этого  - закомментарить сравнение Поз и прогнать чисто чтение. Если будет так же медленно - то проблема в этом. ИМХО : реадлн - не самый шустрый способ прочитать файл.
2. Если будет летать - то оптимизить поиск по строке.


clickmaker   (2008-02-05 11:36:00) [56]


> Owa   (04.02.08 23:24)

RichEdit - плохой кандидат для 2-гиговых логов. Лучше уж просто Memo.
Либо замапить файл и рисовать текст самому - только видимую часть, с учетом прокрутки


хам   (2008-02-05 11:13:00) [57]

> [14] Skyle ©   (05.02.08 11:01)
> Не надо считать, что оптимизация чтения с диска (виндовый
> кэш) и оптимизация обработки внутри программы - это одно
> и то же.

А чего, в [3] я где-то пропустил оптимизацию обработки? Да ито, что в [4] — тоже не оптимизация, а гемморой называется. Оптимизировать по идее нужно pos, но он всяко быстрее диска работает и так…


Skyle   (2008-02-05 11:11:00) [58]


> Игорь Шевченко ©   (05.02.08 11:05) [15]

Задача не моя, просто решил уточнить, что тут более одного этажа.


Игорь Шевченко   (2008-02-05 11:05:00) [59]

Skyle ©   (05.02.08 11:01) [14]

Не надо считать, что чтение большими блоками для ускорения чего-либо и геморрой с пересечением границ буферов есть оптимизация.

Впрочем, все в твоих руках - пишешь тест, читая readln и большими кусками, хронометрируешь, выкладываешь результаты вместе с кодом теста.


Skyle   (2008-02-05 11:01:00) [60]


> хам   (05.02.08 10:42) [13]
> > [12] Skyle ©   (05.02.08 10:29)
> > А мягкое всяко лучше красного. И вообще, это вам не громкое.
>
>
> Рад за тебя.

А я за тебя - нет.

Не надо считать, что оптимизация чтения с диска (виндовый кэш) и оптимизация обработки внутри программы - это одно и то же.


Страницы:   1 2 3 4

Наверх

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