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

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

Сколько строк в файле? [D7, XP]


Страницы:   1 2

operator ©   (2008-03-28 16:43:00) 

Как быстрее всего узнать сколько строк в текствово файле?


Leonid Troyanovsky   (2008-03-29 14:35:00) [1]


> Palladin ©   (29.03.08 00:24) [26]

> тааак... FILE_FLAG_SEQUENTIAL_SCAN то я и забыло

http://groups.google.com/group/fido7.su.win32.prog/msg/e4edc3fb35401f38
http://groups.google.com/group/fido7.su.win32.prog/msg/c166d6d784f3864c

--
Regards, LVT.


Loginov Dmitry   (2008-03-29 00:37:00) [2]

при первом вызове _Tick2 благодаря FILE_FLAG_SEQUENTIAL_SCAN достигается ускорение 13% (файл 1,6 ГБайт, 2ГБ ОЗУ). При втором и последующих вызовах _Tick2 наблюдается значительное падение скорости.


Palladin   (2008-03-29 00:24:00) [3]

тааак... FILE_FLAG_SEQUENTIAL_SCAN то я и забыло... но проверю только заутра :) на WM5 Delphi не работает...

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


Leonid Troyanovsky   (2008-03-28 22:43:00) [4]


> Palladin ©   (28.03.08 18:42) [10]

> чет нифика не пойму я на этих тестах

Все уже проверено до нас.
Быстрее всего последовательное (FILE_FLAG_SEQUENTIAL_SCAN) чтение
с оптимальным размером буфера.

--
Regards, LVT.


tesseract   (2008-03-28 22:08:00) [5]


> У нас пробуют. Правда получают по рукам, вплоть до увольнения,
>  но бывает


Ужас, как таких на работу вообще берут ?


Джо   (2008-03-28 21:54:00) [6]

Господь с вами, что за ужасы. Впрочем, вполне похоже на правду.


MetalFan   (2008-03-28 21:39:00) [7]


> Игорь Шевченко ©   (28.03.08 21:29) [21]

эдакие вы садисты!


Игорь Шевченко   (2008-03-28 21:29:00) [8]

Германн ©   (28.03.08 21:23) [20]

У нас пробуют. Правда получают по рукам, вплоть до увольнения, но бывает.


Германн   (2008-03-28 21:23:00) [9]


> Игорь Шевченко ©   (28.03.08 19:39) [19]

Дык ведь действительно попробует загрузить в Memo!


Игорь Шевченко   (2008-03-28 19:39:00) [10]

Как узнать количество строк в текстовом файле - загрузить его в Memo и посчитать Memo1.Lines.Count


Игорь Шевченко   (2008-03-28 19:35:00) [11]


> выигрыш копейки будет скорее всего...


кстати точно копейки, подтверждаю.


Palladin   (2008-03-28 19:28:00) [12]

ну фиг знает... по хорошему вроде как дОлжно... #26 это ж конец файла... :)


Zeqfreed   (2008-03-28 19:27:00) [13]

> Palladin ©   (28.03.08 19:24) [15]

А должно? Я что сделал. Я сделал шестнадцатиричный дамп образа диска слаки и посчитал в нем строчки. Как видно, было найдено 41430184 строки, т.е. вполне достаточно :)


Palladin   (2008-03-28 19:24:00) [14]

а не прекращает ли cat работу при встрече #26, ась? :)


Zeqfreed   (2008-03-28 19:22:00) [15]

$ cat ~artem/downloads/slackware-12.0-install-d1.iso | hexdump > /tmp/bigfile
$ ls -lh /tmp/bigfile
-rw-r--r-- 1 artem artem 1.9G2008-03-28 21:27 /tmp/bigfile
$ time { cat /tmp/bigfile | wc -l ; }
41430184

real    0m 27.440s
user    0m1.474s
sys     0m3.161s

Это достаточно длинно? :)


Palladin   (2008-03-28 19:06:00) [16]


> Плохиш ©   (28.03.08 18:56) [11]

результат конечно на рыльце, но до MMF недотягивает

RLN:2000000:6391
RLN:2000000:6359
RLN:2000000:6344
RLN:2000000:6359
RLN:2000000:6344
RLN:2000000:6359
6359
MMF:2000000:1032
MMF:2000000:1046
MMF:2000000:1032
MMF:2000000:1047
MMF:2000000:1031
MMF:2000000:1047
1039
RLN32:2000000:3750
RLN32:2000000:3750
RLN32:2000000:3781
RLN32:2000000:3734
RLN32:2000000:3719
RLN32:2000000:3781
3752


претендент

Function GetLinesCountRLNB32(Const p_strFileName:String):Cardinal;
Var
f:TextFile;
Buf:Pointer;
Begin
GetMem(Buf,32*1024*1024);
Result:=0;
AssignFile(f,p_strFileName);SetTextBuf(f,Buf^,32*1024*1024);Reset(f);
While Not Eof(f) Do
 Begin
  Inc(Result);
  Readln(f);
 End;
CloseFile(f);
FreeMem(Buf);
End;


про добавления в Bench рассказывать не буду, и так понятно :)

файл:
2 000 000 строк
размер - 403 373 064b


operator   (2008-03-28 18:57:00) [17]

Спасибо , пойду юзать....


Плохиш   (2008-03-28 18:56:00) [18]


> AssignFile(f,p_strFileName);Reset(f);

А если между ними ещё и SetTextBufпоставить?


Palladin   (2008-03-28 18:42:00) [19]

чет нифика не пойму я на этих тестах

Function GetLinesCountMMF(Const p_strFileName:String):Cardinal;
Const
BUF_SIZE=32*1024*1024;

Type
TFileMapRec=Record
_File:HFILE;
_Map:THandle;
_Size:Int64;
End;

Function OpenFile(Const p_strFileName:String):TFileMapRec;
Var
slo,shi:Cardinal;
Begin
Result._File:=CreateFile(PChar(p_strFileName), GENERIC_READ,FILE_SHARE_READ,Nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
slo:=Windows.GetFileSize(Result._File,@shi);
Int64Rec(Result._Size).Lo:=slo;
Int64Rec(Result._Size).Hi:=shi;
Result._Map:=CreateFileMapping(Result._File,Nil,PAGE_READONLY,0,0,Nil);
End;

Procedure CloseFile(Var rp_rFile:TFileMapRec);
Begin
CloseHandle(rp_rFile._Map);
CloseHandle(rp_rFile._File);
End;

Function MapBuff(p_rFile:TFileMapRec;p_nFrom:Int64;p_nCount:Cardinal):Pointer;
Begin
Result:=MapViewOfFile(p_rFile._Map, FILE_MAP_READ,Int64Rec(p_nFrom).Hi,Int64Rec(p_nFrom).Lo,p_nCount);
End;

Procedure UnMapBuff(Var p:Pointer);
Begin
UnmapViewOfFile(p);
End;

Var
_File:TFileMapRec;
Buf:PByteArray;
p:Int64;
LastBufByteIsCR:Boolean;

Function _Count(p_nFrom:Int64;p_nCount:Cardinal):Cardinal;
Var
StartFrom:Integer;
i:Integer;
Begin
Buf:=MapBuff(_File,p_nFrom,p_nCount);
Try
 Result:=0;
 If Not LastBufByteIsCR Then StartFrom:=0 Else
  If Buf[0]<>10 Then StartFrom:=0 Else
   Begin
    Inc(Result);
    StartFrom:=1;
   End;
 For i:=StartFrom to p_nCount-2 Do
  If (Buf[i]=13) and (Buf[i+1]=10) Then Inc(Result);
 LastBufByteIsCR:=Buf[p_nCount-1]=13;
Finally
 UnMapBuff(Pointer(Buf));
End;
End;

Begin
_File:=OpenFile(p_strFileName);
Try
 p:=0;
 Result:=0;
 While True Do
  If (p+BUF_SIZE)>_File._Size Then
   Begin
    Result:=Result+_Count(p,_File._Size-p);
    Break;
   End Else
   Begin
    Result:=Result+_Count(p,BUF_SIZE);
    Inc(p,BUF_SIZE);
   End;
Finally
 CloseFile(_File);
End;
End;

Function GetLinesCountRLN(Const p_strFileName:String):Cardinal;
Var
f:TextFile;
Begin
Result:=0;
AssignFile(f,p_strFileName);Reset(f);
While Not Eof(f) Do
 Begin
  Inc(Result);
  Readln(f);
 End;
CloseFile(f);
End;

Function vtRandomStr(p_nMaxLen:Integer=300):String;
Var
i:Integer;
Begin
SetLength(Result,Random(p_nMaxLen));
For i:=1 to Length(Result) Do
 Result[i]:=Char(Random(223)+32);
End;

procedure TForm1.CreateRndTxtFile;
Var
i:Integer;
f:TextFile;
begin
AssignFile(f,'c:\bigtext.txt'); Rewrite(f);
For i:=0 to 2000000-1 Do WriteLn(f,vtRandomStr(400));
CloseFile(f);
end;

procedure TForm1.Bench;
Var
gtc:Cardinal;
tc:Cardinal;
i:Integer;

Procedure _Tick1;
Begin
 tc:=GetTickCount;
 Memo1.Lines.Add('RLN:'+IntToStr(GetLinesCountRLN('c:\bigtext.txt'))+':'+IntToStr(GetTickCount-tc));
 Application.ProcessMessages;
End;

Procedure _Tick2;
Begin
 tc:=GetTickCount;
 Memo1.Lines.Add('MMF:'+IntToStr(GetLinesCountMMF('c:\bigtext.txt'))+':'+IntToStr(GetTickCount-tc));
 Application.ProcessMessages;
End;

begin
gtc:=GetTickCount;
For i:=0 to 5 Do _Tick1;
Memo1.Lines.Add(IntToStr((GetTickCount-gtc) div 6));
Application.ProcessMessages;
gtc:=GetTickCount;
For i:=0 to 5 Do _Tick2;
Memo1.Lines.Add(IntToStr((GetTickCount-gtc) div 6));
Application.ProcessMessages;
end;


на объемах мегабайт в 400-500, MMF выигрывает по скорости в 5 раз, на объеме в 1.9Гб (10 млн строк я создал файл), выигрыш копеечный...

видимо очень сильно влияет внутренний буффер IO системы и наличие памяти...

WinXP, SP2, 1.5Гб ОЗУ


Плохиш   (2008-03-28 18:04:00) [20]


>   readln(r,s);

readln(r);


Страницы:   1 2

Наверх

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