Schrift
[thread]6203[/thread]

Anzahl Zeilen in Textdatei ermitteln: (Wie mache ich das am schnellsten?)



<< |< 1 2 3 4 >| >> 35 Einträge, 4 Seiten
Crian
 2004-04-21 11:58
#81696 #81696
User since
2003-08-04
5866 Artikel
ModeratorIn
[Homepage]
user image
Was mag die schnellste Variante sein, um die Anzahl an Zeilen in einer Textdatei zu ermitteln?

1.) In einer Whileschleife durchlaufen (die Datei muss dafür ganz gelesen werden) und immer einen Zähler hochzählen?

2.) Tie::File verwenden, scalar @array, untie?

3.) Aufruf von wc -l und hoffen, dass es vorhanden ist

4.) ?


Ideen, Tipps, Erfahrungen, Meinungen? :-)
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
[E|B]
 2004-04-21 13:21
#81697 #81697
User since
2003-08-08
2561 Artikel
HausmeisterIn
[Homepage] [default_avatar]
Anderer Vorschlag:

Code: (dl )
1
2
3
open(F, "file.txt");
print scalar(@array = <F>);
close(F);
Gruß, Erik!

s))91\&\/\^z->sub{}\(\@new\)=>69\&\/\^z->sub{}\(\@new\)=>124\&\/\^z->sub{}\(\@new\)=>);
$_.=qq~66\&\/\^z->sub{}\(\@new\)=>93~;for(@_=split(/\&\/\^z->sub{}\(\@new\)=>/)){print chr;}

It's not a bug, it's a feature! - [CGI-World.de]
Taulmarill
 2004-04-21 13:24
#81698 #81698
User since
2004-02-19
1750 Artikel
BenutzerIn

user image
hm, im zweifelsfall benchmarken.
aber da es meines wissens keine schnellere lösung gibt als alle zeilenumbrüche zu zählen würde ich die methode mit der while schleife bevorzugen.
$_=unpack"B*",~pack"H*",$_ and y&1|0& |#&&print"$_\n"for@.=qw BFA2F7C39139F45F78
0A28104594444504400 0A2F107D54447DE7800 0A2110453444450500 73CF1045138445F4800 0
F3EF2044E3D17DE 8A08A0451412411 F3CF207DF41C79E 820A20451412414 83E93C4513D17D2B
Taulmarill
 2004-04-21 13:26
#81699 #81699
User since
2004-02-19
1750 Artikel
BenutzerIn

user image
[E|B
,21.04.2004, 11:21]Anderer Vorschlag:

Code: (dl )
1
2
3
open(F, "file.txt");
print scalar(@array = <F>);
close(F);

oha! du willst die ganze file in einen array lesen?!?
bei einer datei die so gross ist, dass man sich um die performance einer blossen zeilenzählung gedanken macht würde ich mir das aber noch mal überlegen.

@crain: wie gross ist die datei denn? und wie viel RAM hat deine Maschiene?
$_=unpack"B*",~pack"H*",$_ and y&1|0& |#&&print"$_\n"for@.=qw BFA2F7C39139F45F78
0A28104594444504400 0A2F107D54447DE7800 0A2110453444450500 73CF1045138445F4800 0
F3EF2044E3D17DE 8A08A0451412411 F3CF207DF41C79E 820A20451412414 83E93C4513D17D2B
[E|B]
 2004-04-21 13:29
#81700 #81700
User since
2003-08-08
2561 Artikel
HausmeisterIn
[Homepage] [default_avatar]
Wenn das ein Dateichen ist brauchst du weder eine Schleife noch ein Modul.
Wenn das so eine rießen Datei ist ok, dann ist der Vorschlag natürlich unangebracht. Aber ich glaube kaum, dass bei kleineren Dateien ein so imenser Performanceverlust vorliegt.

Ich glaube es ist Zeit für Benchmark.pm. :D
Gruß, Erik!

s))91\&\/\^z->sub{}\(\@new\)=>69\&\/\^z->sub{}\(\@new\)=>124\&\/\^z->sub{}\(\@new\)=>);
$_.=qq~66\&\/\^z->sub{}\(\@new\)=>93~;for(@_=split(/\&\/\^z->sub{}\(\@new\)=>/)){print chr;}

It's not a bug, it's a feature! - [CGI-World.de]
ptk
 2004-04-21 13:31
#81701 #81701
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
Die Reihenfolge (ohne zu benchmarken) duerfte 3 - 1 - 2 sein. In C geschriebene Programme werden meistens schneller sein, sobald die Laufzeit des Programms den Overhead des zusaetzlichen Prozessaufrufs ueberwiegt. Tie::File duerfte am langsamsten sein, da hier zusaetzliche Datenstrukturen (e.g. Seek-Positionen von jeder Zeile) verwaltet werden, die nur Zeit und Speicher (und wegen der deshalb noetigen malloc- und sbrk-Aufrufe wiederum Zeit) verbrauchen.
Taulmarill
 2004-04-21 13:34
#81702 #81702
User since
2004-02-19
1750 Artikel
BenutzerIn

user image
also ich kann jetzt schon sagen, dass ich heute keine zeit zum benchmarken hab.
wenn das ein dateichen ist, dann muss man sich keine gedanken um performance machen, für den fall finde ich deinen code sehr elegant.

aber wenn du mal in den originalpost schaust, geht es da um die schnellste variante. ich hatte da jetzt schnell mit performant gleichgesetzt und nicht mit schnell programmiert.
$_=unpack"B*",~pack"H*",$_ and y&1|0& |#&&print"$_\n"for@.=qw BFA2F7C39139F45F78
0A28104594444504400 0A2F107D54447DE7800 0A2110453444450500 73CF1045138445F4800 0
F3EF2044E3D17DE 8A08A0451412411 F3CF207DF41C79E 820A20451412414 83E93C4513D17D2B
Crian
 2004-04-21 13:37
#81703 #81703
User since
2003-08-04
5866 Artikel
ModeratorIn
[Homepage]
user image
Ich weiß nicht genau, wie groß die Dateien werden können... bisher kamen aber schon welche mit um 1,2 Mio Zeilen vor. Und man könnte sie noch in den Hauptspeicher (512MB) einlesen, aber das macht man natürlich nur ungern, zumal wenn es nicht nötig ist.

Die Datei wird später eh nochmal Zeile für Zeile eingelesen und verarbeitet, ich möchte nur gerne den Fortschritt der Arbeit in Prozenten ausrechnen können, das kann ich aber natürlich nur, wenn ich vorher weiß, wieviele Zeilen die Datei hat. Und dieses nice-to-have darf natürlich nicht signifikant Zeit kosten.

Ich denke ich bau es einfach ein und schau mal... ums Zählen der Umbrüche kommt man wohl wirklich nicht herum.

Ich dachte nur, vielleicht wäre Tie::File und dann die Arraygröße ermitteln irgendwie schlau, aber dafür muss er ja auch mindestens alle Umbrüche zählen...

[quote=Taulmarill,21.04.2004, 11:34]also ich kann jetzt schon sagen, dass ich heute keine zeit zum benchmarken hab.
wenn das ein dateichen ist, dann muss man sich keine gedanken um performance machen, für den fall finde ich deinen code sehr elegant.

aber wenn du mal in den originalpost schaust, geht es da um die schnellste variante. ich hatte da jetzt schnell mit performant gleichgesetzt und nicht mit schnell programmiert.[/quote]
genau ;-)

schnell programmiert wäre kürzer gewesen als die Frage zu stellen :-D\n\n

<!--EDIT|Crian|1082540383-->
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
jan
 2004-04-21 13:57
#81704 #81704
User since
2003-08-04
2536 Artikel
ModeratorIn
[Homepage] [default_avatar]
sonst nimm doch einfach die dateigröße und lass anschließend den fortschritt durch die anzahl der verarbeiteten bytes anzeigen, nach dem motto "eine lange zeile mit mehr daten kostet mehr zeit", das spart dir den ersten zählvorgang komplett und ist auch nicht ganz so schlimm ;)
Taulmarill
 2004-04-21 14:02
#81705 #81705
User since
2004-02-19
1750 Artikel
BenutzerIn

user image
arrggg, kann ... mich nicht .... zurückhalten....
muss ... benchmarken .....

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/perl -w

use strict;
use Benchmark;

timethese(5, {
A => sub {
open ( FILE, "<test.txt" );
my $ln;
while ( <FILE> ) {
$ln++;
}
close (FILE);
},
B => sub {
open ( FILE, "<test.txt" );
my @array;
my $ln = scalar(@array = <FILE>);
close (FILE);
}
});


Code: (dl )
1
2
3
Benchmark: timing 5 iterations of A, B...
A: 24 wallclock secs (23.49 usr + 0.34 sys = 23.83 CPU) @ 0.21/s (n=5)
B: 54 wallclock secs (52.74 usr + 1.40 sys = 54.14 CPU) @ 0.09/s (n=5)


text.txt ist 20267625 Bytes gross und hat 1.200.000 Zeilen
$_=unpack"B*",~pack"H*",$_ and y&1|0& |#&&print"$_\n"for@.=qw BFA2F7C39139F45F78
0A28104594444504400 0A2F107D54447DE7800 0A2110453444450500 73CF1045138445F4800 0
F3EF2044E3D17DE 8A08A0451412411 F3CF207DF41C79E 820A20451412414 83E93C4513D17D2B
<< |< 1 2 3 4 >| >> 35 Einträge, 4 Seiten



View all threads created 2004-04-21 11:58.