Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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
15-1205498404
question
2008-03-14 15:40
2008.04.27
Помогите пожалуйста определиться с ценой разработки.


4-1188132659
Asker
2007-08-26 16:50
2008.04.27
Изменение свойств scrollbar у TreeView


15-1205120451
Denis__
2008-03-10 06:40
2008.04.27
Школа будущего.


2-1207056885
Res
2008-04-01 17:34
2008.04.27
Послать


15-1205675818
Loginov Dmitry
2008-03-16 16:56
2008.04.27
Очередное обновление Matrix32