HI Aristoteles,<br>
<br>
danke, mein Kuerzen macht das Lesen wirklich nicht leichter ;-) <br><br><div><span class="gmail_quote">2006/1/17, A. Pagaltzis <<a href="mailto:pagaltzis@gmx.de">pagaltzis@gmx.de</a>>:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Hi Johannes,<br><br>* Johannes Huettemeister <<a href="mailto:j.huettemeister@googlemail.com">j.huettemeister@googlemail.com</a>> [2006-01-16 20:55]:<br>>ich hab hier ein Codeschnipsel fabriziert, das funktioniert,
<br>>aber mit Sicherheit optimiert werden kann.<br><br>An Optimierung würde ich erst garnicht denken, jedenfalls nicht<br>im Sinne von Geschwindigkeit; der Code ist in der vorliegenden<br>Form völlig unlesbar. Ich habe gut 5 Minuten draufstarren müssen,
<br>bis mir klar war, wie die Bauteile alle zusammenpassen.</blockquote><div><br>
Das liegt wohl am Entstehen. Ging zwar sehr schnell aber war viel Trial und Error und ich hab nachher nicht *sauber* gemacht.<br>
<br>
</div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">>sysopen (FILE, $filename, O_RDONLY) or die "$!";<br>>seek(FILE,$offset,$startpos);
<br>><br>>my $b = ''; my @f; $togo = 0;<br>>for ($curpos = tell(FILE); my $c = read(FILE, $b, 1024, length($b)) ;<br>>$curpos = tell(FILE)) {<br>> @f = split(/^/m, $b);<br>> foreach (@f) {<br>> unless (m,\n,) {
<br>> $b = $_;<br>> last;<br>> }<br>> do_something_with_line<br>> }<br>> last if ($togo++ == 5000);.<br>>}<br><br>Vor allem ist der Code fehlerhaft:<br><br>
1. Du setzt `$b` nur dann zurück, wenn eine Zeile kein `\n`<br> enthält. Wenn du also einen 1024er-Happen Daten einliest, der<br> zufällig genau am Ende einer Zeile endet, dann wird `$b`<br> nirgendwo geleert, und der nächste Durchlauf der Schleife
<br> wird die Daten dann doppelt verarbeiten.<br><br> Das ist es, was mir das Verständnis so erschwert hat: es<br> schien, als wolltest du Daten früherer Durchläufe mehrfach<br> verarbeiten, was offensichtlich ja nicht die Absicht ist.
</blockquote><div><br>
Das waere ein ganz boeser Bug geworden. Ist zwar beim Test nicht passiert (fuer 3GB), aber irgendwann sicher.<br>
<br>
</div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">2. Wenn die letzte Zeile der Datei nicht auf ein `\n` endet,<br> schmeisst du sie weg.
</blockquote><div><br>
Wuerde bei den Inputdaten nicht vorkommen, aber man weiss ja nie.<br>
</div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">3. Wenn der letzte der 5000 der 1024er-Happen nicht genau auf<br> ein Zeilenende endet, wirfst du Daten weg, weil die innere
<br> Schleife dann zwar diesen Rest nach `$b` zuweist, die äussere<br> aber kein weiteres Mal mehr durchläuft. Und du spulst den<br> Dateicursor auch nicht zurück, um diese Daten beim nächsten<br> Lauf mitzunehmen.
<br><br>Ausserdem ist es merkwürdig, dass du so obsessiv bei jedem<br>Schleifendurchlauf `$curpos` speicherst. Wenn der hier gezeigte<br>Code nicht zu unvollständig ist, reicht es, das *ein* einziges<br>Mal *nach* der Schleife zu machen.
</blockquote><div><br>
Das hab ich irgendwo aus dem perl bookshelf, programming perl unter seek mein ich.<br>
<br>
Gruss Jo.<br>
</div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">Warum du hier `sysopen` verwendest, ist unklar; und du solltest<br>lieber mit lexikalischen Filehandles arbeiten statt Barewords.
<br><br>Zuguterletzt: statt selber `$togo` zu verwalten, würde ich eher<br>eine `foreach`-Schleife von 1-5000 nehmen, aus der ich bei Bedarf<br>nach dem Lesen per `last` aussteige.<br><br>Summa summarum:<br><br> open my $fh, '<', $filename
<br> or die "$!";<br><br> seek $fh, $offset, $startpos;<br><br> # on each iteration, $buf may contain the start of<br> # an incomplete line from the end of the previous<br> # iteration's chunk of data
<br> my $buf = '';<br><br> my $chunk_len = 1024;<br><br> for( 1 .. 5000 ) {<br><br> my $read_len = read( $fh, $buf, $chunk_len, length $buf )<br> or last;<br><br> my @line = split /^/m, $buf;
<br><br> $buf = ( $line[ -1 ] =~ /\n\z/ ) || ( $read_len != $chunk_len )<br> ? ''<br> : pop @line;<br><br> foreach ( @line ) {<br> do_something_with_line();<br> }<br><br>
}<br><br> $curpos = tell $fh;<br><br> # account for unprocessed data<br> $curpos -= do {<br> use bytes;<br> length $buf;<br> };<br><br>Gruss,<br>--<br>#Aristoteles<br>*AUTOLOAD=*_;sub _{s/(.*)::(.*)/print$2,(",$\/"," ")[defined wantarray]/e;$1};
<br>&Just->another->Perl->hacker;<br>_______________________________________________<br>Cologne-pm mailing list<br><a href="mailto:Cologne-pm@pm.org">Cologne-pm@pm.org</a><br><a href="http://mail.pm.org/mailman/listinfo/cologne-pm">
http://mail.pm.org/mailman/listinfo/cologne-pm</a></blockquote></div><br>