Текущий архив: 2008.04.27;
Скачать: CL | DM;
Вниз
Сколько строк в файле? Найти похожие ветки
← →
operator © (2008-03-28 16:43) [0]Как быстрее всего узнать сколько строк в текствово файле?
← →
Сергей М. © (2008-03-28 16:50) [1]Быстрее всего будет подсчитать кол-во вхождений символов разделителей (или последовательностей символов-разделителей) строк.
← →
Palladin © (2008-03-28 16:51) [2]Причем правильно прочитать :) а не бредить в исходниках...
← →
operator © (2008-03-28 17:45) [3]
var r:textfile; s:string;
begin
assignfile(r,filename);
reset(r);
al:=0;
while not eof(r) do begin
inc(al);
readln(r,s);
end;
closefile(r);
вот такая мутатень не радует...
а вообще через что следует реализовывать? то есть в сторону чего думать )
← →
Palladin © (2008-03-28 17:50) [4]это правильная мутотень, ты не сможешь узнать сколько карт из 10 черного цвета не перебрав их все...
← →
operator © (2008-03-28 17:57) [5]просто как-то медленно работает... думал может есть средство какое-нибудь готовое)
← →
Palladin © (2008-03-28 17:58) [6]ну вот теперь есть, ты ж его написал, вот оно теперь и готовое
← →
clickmaker © (2008-03-28 17:59) [7]
> а вообще через что следует реализовывать? то есть в сторону
> чего думать
CreateFile - CreateFileMapping - MapViewOfFile
подсчет в буфере символов #13 или #10
UnmapViewOfFile - CloseHandle - CloseHandle
← →
Palladin © (2008-03-28 18:01) [8]
> clickmaker © (28.03.08 17:59) [7]
выигрыш копейки будет скорее всего... и сложнее все гораздо чем просто подсчет символов #13 или #10, бо они в паре идут... хотя ща попробую наваять и потестировать...
← →
Плохиш © (2008-03-28 18:04) [9]
> readln(r,s);readln(r);
← →
Palladin © (2008-03-28 18:42) [10]чет нифика не пойму я на этих тестах
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:56) [11]
> AssignFile(f,p_strFileName);Reset(f);
А если между ними ещё и SetTextBuf поставить?
← →
operator © (2008-03-28 18:57) [12]Спасибо , пойду юзать....
← →
Palladin © (2008-03-28 19:06) [13]
> Плохиш © (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
← →
Zeqfreed © (2008-03-28 19:22) [14]$ cat ~artem/downloads/slackware-12.0-install-d1.iso | hexdump > /tmp/bigfile
$ ls -lh /tmp/bigfile
-rw-r--r-- 1 artem artem 1.9G 2008-03-28 21:27 /tmp/bigfile
$ time { cat /tmp/bigfile | wc -l ; }
41430184
real 0m27.440s
user 0m1.474s
sys 0m3.161s
Это достаточно длинно? :)
← →
Palladin © (2008-03-28 19:24) [15]а не прекращает ли cat работу при встрече #26, ась? :)
← →
Zeqfreed © (2008-03-28 19:27) [16]> Palladin © (28.03.08 19:24) [15]
А должно? Я что сделал. Я сделал шестнадцатиричный дамп образа диска слаки и посчитал в нем строчки. Как видно, было найдено 41430184 строки, т.е. вполне достаточно :)
← →
Palladin © (2008-03-28 19:28) [17]ну фиг знает... по хорошему вроде как дОлжно... #26 это ж конец файла... :)
← →
Игорь Шевченко © (2008-03-28 19:35) [18]
> выигрыш копейки будет скорее всего...
кстати точно копейки, подтверждаю.
← →
Игорь Шевченко © (2008-03-28 19:39) [19]Как узнать количество строк в текстовом файле - загрузить его в Memo и посчитать Memo1.Lines.Count
← →
Германн © (2008-03-28 21:23) [20]
> Игорь Шевченко © (28.03.08 19:39) [19]
Дык ведь действительно попробует загрузить в Memo!
← →
Игорь Шевченко © (2008-03-28 21:29) [21]Германн © (28.03.08 21:23) [20]
У нас пробуют. Правда получают по рукам, вплоть до увольнения, но бывает.
← →
MetalFan © (2008-03-28 21:39) [22]
> Игорь Шевченко © (28.03.08 21:29) [21]
эдакие вы садисты!
← →
Джо © (2008-03-28 21:54) [23]Господь с вами, что за ужасы. Впрочем, вполне похоже на правду.
← →
tesseract © (2008-03-28 22:08) [24]
> У нас пробуют. Правда получают по рукам, вплоть до увольнения,
> но бывает
Ужас, как таких на работу вообще берут ?
← →
Leonid Troyanovsky © (2008-03-28 22:43) [25]
> Palladin © (28.03.08 18:42) [10]
> чет нифика не пойму я на этих тестах
Все уже проверено до нас.
Быстрее всего последовательное (FILE_FLAG_SEQUENTIAL_SCAN) чтение
с оптимальным размером буфера.
--
Regards, LVT.
← →
Palladin © (2008-03-29 00:24) [26]тааак... FILE_FLAG_SEQUENTIAL_SCAN то я и забыло... но проверю только заутра :) на WM5 Delphi не работает...
если кому то захочется пораньше, то вперед, копи паст никто не отменял
← →
Loginov Dmitry © (2008-03-29 00:37) [27]при первом вызове _Tick2 благодаря FILE_FLAG_SEQUENTIAL_SCAN достигается ускорение 13% (файл 1,6 ГБайт, 2ГБ ОЗУ). При втором и последующих вызовах _Tick2 наблюдается значительное падение скорости.
← →
Leonid Troyanovsky © (2008-03-29 14:35) [28]
> 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.
Страницы: 1 вся ветка
Текущий архив: 2008.04.27;
Скачать: CL | DM;
Память: 0.54 MB
Время: 0.012 c