[linux-l] Ruby: sehr cool, aber auch sehr laaaahm... wie geht's schneller?!

Steffen Dettmer steffen at dett.de
Di Aug 22 10:43:25 CEST 2006


* Oliver Bandel wrote on Mon, Aug 21, 2006 at 13:48 +0200:
> Das wird aber auch nicht schneller.... sollte es aber,
> denn die Datei dürfte ja nach dem throw nicht mehr zuende gelesen
> werden müssen. 

Wie gross sind die Files? So eher klein? Dann würde mich das nicht
überraschen, denn vermutlich wird da eh blockweise gecacht etc. 3
Sekunden ist natürlich fett... Sind das viele kleine oder wenige grosse
Dateien?

Ist aber witzig, dass es bei Abbruch nicht schneller wird, find ich auch
spannend :-)

> Allerdings sagen mir die Ausführungszeiten, daß anscheinend doch alle
> Files bis zum bitteren Ende gelesen werden...?!

strace hilft bei solchen Fragen manchmal.

> Perl-Version zum Vergleich:
> ---------------------------
> 
> 
> ========================================
>   foreach (@ARGV)
>   {
>     open FILE, "$_"  or next;
>     while(<FILE>)
>     {
>       if( /^begin/ )
>       {
>         print;
>         #close FILE;
>         #next;
>       }
>     }
>     close FILE;
>   }
> ========================================
> 
> ca. 1,7 Sekunden mit den Kommentaren,
> ca. 0,8 Sekunden wenn man die Kommentarzeichen entfernt

Na ja, also mit Zeiten muss man sehr aufpassen... Bei mir dauert Dein
Beispiel:

steffen at link:~/5> time ./test.pl *rar

real    0m2.457s
user    0m0.370s
sys     0m0.170s
steffen at link:~/5> time ./test.pl *rar

real    0m0.488s
user    0m0.300s
sys     0m0.180s

direkt hintereinander, schlägt OS Cache natürlich zu :)

Das oben funktioniert, weil "while(<FILE>)" mit Fehler zurückkommt, wenn
das "#next" auf der geschlossenen Datei liest und "fertig" ist?

Würde statt dem close/next lieber einfach ein last oder ein break
nehmen, oder dem foreach ein label file oder so ("FILE: foreach(x))
geben und dann mit next FILE; anspringen.


Zu der Performance: ja, geh davon aus, dass stringvergleiche schneller
sind als regex, ABER wenn man z.B. 
  /^begin/ 
mit
  str.strstr("begin") == 0
abbildet (also "Sub-String-Suche"), wirds natürlich langsam. Wenn begin
nicht drin ist, muss strstr den ganzen String durchsuchen (könnte ja an
index 10341231 noch ein begin kommen). Der RegEx kann optimieren, wenn's
halt nicht am Anfang war und muss nicht weitersuchen, strstr weiss das
aber ja nicht. Dann lieber substr auf strlen des "begin" und "eq" oder
strcmp Vergleiche mit dem Ergebnis, strncmp sollte hier noch schneller
sein, wenn man es hat. Sowas ist dann eigentlich immer sehr schnell, es
"fasst keine nicht benötigen Bytes an", bei langen Zeilen hier natürlich
sehr wichtig. Ich glaub, schneller kriegt man das dann nicht.

Das langsame kommt dann wieder vom "gets" oder was man da nimmt, das
muss mindestens newlines suchen. Kann man aber geschickt (mit caching
etc) implementieren. Ich würde immer erwarten, dass sowas schnell
implementiert ist.

Unterm Strich würde ich raten, dass es am schnellsten sein sollte,
"\nbegin" im File-input zu suchen.

> So etwas (speedup) hätte ich bei meinen Ruby-Lösungen auch erwartet.

Ja, komisch...

oki,

Steffen

-- 
Dieses Schreiben wurde maschinell erstellt,
es trägt daher weder Unterschrift noch Siegel.




Mehr Informationen über die Mailingliste linux-l