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

Oliver Bandel oliver at first.in-berlin.de
Di Aug 22 08:35:04 CEST 2006


Moin Volker,


On Tue, Aug 22, 2006 at 01:16:54AM +0200, Volker Grabsch wrote:
> On Mon, Aug 21, 2006 at 01:48:18PM +0200, Oliver Bandel wrote:
> > seit kurzem schaue ich mir Ruby an.
> > 
> > Echt coole Sprache.
> > Da kann man sich das mit dem OO ja doch wieder angewöhnen ;-)
> 
> Ja, die Syntax sieht schön aus.

Ja, das meinte ich mit meinen Äußerungen zur Sprache.
Schöner Code, finde ich.


> (im Vergleich zu z.B. Ocaml oder Python, und erst recht im
> Vergleich zu C/C++/Java ;-))
> 
> Aber ich persönlich finde die Sprache nicht gut designt.
> Unter den dynamisch typisierten Sprachen finde ich nach
> wie vor Python super designt, da könnte höchstens Scheme
> mithalten (nicht kosmetisch, aber konzeptionell).
[...]

Ich kenne von den dynamischen Sprachen bisher nur Perl.
Python wollte ich mir auch schon lange, lange anschauen,
aber habe ich halt noch nicht gemacht.

Ich dachte, daß Ruby das beste aus allen dynamischen Welten
eingesammelt hat und daher auch best-designed ist...

...lieg' ich da also falsch? :(

Naja, wenn ich es näher kenne, kann ich mir dazu ein Bild machen.

Ruby kam bei mir so nach "Eierlegender Wollmilchsau" rüber,
und soll derzeit woohl an Popularität sehr zulegen...
...da dachte ich dann, ist es denn mal Zeit sich das endlich anzuschauen.

Hattest Du nicht auch Ruby sehr hervorgehoben bisher?



> 
> Ich habe viele buggige Ruby-Bibliotheken gefunden, und ich
> glaube nicht, dass sie alle auf die kleinere Community
> zurück zu führen sind. Diese übermäßig komplexe Basis-Klasse
> "object", die von anderen Modulen nachträglich sogar weiter
> aufgebläht wird, ist z.B. genau das, was in Python viel, viel
> besser gemacht wurde. Ditto für I/O-Streams.

Oh jeh... jetzt nur nicht demotivieren lassen ;-)
... nicht daß ich das "jetzt lerne ich Ruby" doch noch hinschmeisse ;-)




> 
> Ich hatte damals Ruby vor Python gelernt. Pythons Syntax
> erschien mir anfangs zu obskur, aber ich habe mich schnell
> daran gewöhnt. Rubys Syntax finde ich immer noch schöner,
> dennoch sind meine Ruby-Programme niemals so schön wie die
> Python-Programme geworden. Zwar gibt es einige Konzepte,
> die sich Python von Ruby abschauen sollte, aber die sind
> IMHO weniger wichtig.
> 
> Dir als OCaml-Fan, der mir in Sachen Perfektionismus wahr-
> scheinlich sehr ähnlich ist, würde ich daher dringend eher
> zu Python raten.


Oha... oh jeh ;-(

Auf's falsche Pferd gesetzt?!

Naja, egal, dann kommt eben Python nach Ruby dran. ;-)

Ich mag bei Ruby z.B. (u.a.) diese awk-ähnlichen Konstrukte,
wo man einen Block mit { ... } anderen Anweisungen
gegenüber "assoziiert".



> 
> > Leider ist die Sprache wohl etwas langsam, aber
> > OK wäre es, wenn die für die meisten Scripting-Sachen
> > schnell genug ist. Sollte meist reichen.
> 
> Es kommt immer auf den Anwendungszweck an. Normalerweise
> werden Ruby/Python genutzt, um die "großen" Dinge zu
> programmieren. Details, die Performance brauchen (z.B.
> "multiple-precision arithmetics" oder XML-Parser), werden
> in anderen Sprachen geschrieben.


Also, wenn das im RealLife tats. so ist, soll#s mir recht sein...
...der Markt für OCaml-Programmierer ist ja noch nicht all zu groß ;-)
(und solange es noch an der triumphalen Geschäftsidee mangelt,
 bei der ich OCaml nutzen kann... *grübel, grübel* ;-))




> 
> Für diesen Zweck gibt es Profiler, die heutzutage immer
> noch viel zu wenig genutzt werden (auch nicht von mir,
> muss ich zu meiner Schande gestehen). Da sucht man sich
> die *echten* Flaschenhälse raus (da verschätzt man sich
> gerade in großen Programmen sehr schnell), und optimiert
> sie, zur Not durch Reimplementierung in C.
> (Ocaml wäre natürlich cooler, weil etwa genauso schnell,
> aber robust)

Wenn man aber z.B. Rzby und OCaml verbinden will,
dann müsste man da die Brücke via C schlagen.
Sowohl OCaml als anscheinend auch Ruby sollen
ja das Einbinden von C-Code einfach machen.
Wenn man aber beide Welten verbinden will, dann muß man sich
da via C eine Schnittstelle bauen.
Wie sowas wohl aussehen würde?!



[...Performance-Optimierung...]
> Auf sowas sollte man aber niemals optimieren, weil das
> bei anderen Interpreter-Implementierungen oder auf anderen
> Betriebssystemen total anders aussehen kann. Auch zukünftige
> Implementierungen werden immer auf die gebräuchlichen Muster
> optimiert werden, sodass gutes, einfaches Design auch in
> Sachen Performance die besten Zukunfts-Aussichten hat.

Naja, soooo viele Ruby-Interpreter gibt's ja noch nicht ;-)


> 
> > Naja gut, am Wochenende habe ich erstmals geRuby't. Werden
> > sicherlich noch ein paar Kniffe da sein, die ich zu lernen habe
> > (was aber sicherlich recht flott geht).
> 
> Ich habe am WE mit Ocaml herumgespielt.

heheh, fein. :)

> Nun gut, mein Programm
> war wirklich ein Paradebeispiel für etwas, wo mir ein gutes
> Typsystem sehr entgegen kommt, und die uralte Implementierung
> war in C++, aber dennoch hat es mich positiv überrascht, wie
> einfach und "straight forward" ich voran gekommen bin.

Oha... hast Du hauptsächlich imperativ bzw. OO-like programmiert,
oder auch funktionale Ansätze verstärkt genutzt?

> Im
> Moment sind nur die wichtigsten Funktionen implementiert, aber
> sobald das Programm eine "sichtbare" Ausgabe liefert, werd
> ich es dir auf jeden Fall zeigen und würde gerne deine
> Meinung zum Programm-Design haben.

Gerne.
Ich würde zwar nicht behaupten Star-Designer zu sein ;-)
aber wenn ich dazu was sagen kann, tu ich's. :)


> 
> Es gab sehr wenig Tippfehler, die Sprache ist in dieser
> Richtung also wirklich wie Ruby/Python, nicht wie C/C++/Java.
> Die sonstigen Fehler, die der Compiler fand, basierten in
> der Tat auf Schlampigkeiten und/oder Denkfehler. Der Ocaml-
> Compiler versteht mich in der Tat besser als Ruby/Pythons
> Exception-System. Ich habe das "böse auf die Finger hauen"
> des Ocaml-Compilers noch nicht erlebt,

Aha, na das ist gut.

> im Gegenteil: Ich
> verwende den Compiler, um meinen Programmier-Stil zu
> verbessern. Wie? Indem ich "-w A" mache, also alle Warnungen
> an. Dann kann selbst ein Pedant noch was vom Compiler lernen.
> Eine zusätzliche Warnung, sie klang total belanglos, war
> aber bei genauerem Nachdenken wirklich berechtigt, und hat
> mich auf etwas aufmerksam gemacht, dass ich vorher zu wenig
> beachtet hatte.

Was für Warnungen waren das (oder was für eine war das, Du hast da wohl
eine spezielle im Sinn?!).


[...Ruby-Code...]
> > 
> > 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. Allerdings sagen mir die Ausführungszeiten, daß
> > anscheinend doch alle Files bis zum bitteren Ende gelesen werden...?!
> 
> Wie viele Dateien sind es denn? Vielleicht wird die Mammut-Zeit
> vom Öffnen der Dateien und nicht vom Auslesen gefressen?
> (zumal das Auslesen ja gecached wird)

188 Dateien, zusammen 16174580 Bytes.


> 
> Um sicher zu gehen, kannst du ja mal sowas wie "break" benutzten,
> anstelle der Exception.
> (weiß jetzt nicht, wie das "break" in Ruby heißt)

Ja, break war das erste was ich ausprobierte; dann habe ich exceptions ausprobiert.
Zum Schluss dachte ich noch: statt break mal return zu nehmen (falls ich da
was übersehen hätte bzgl. Reichweite von break...).
Aber auch das return brachte keinen Geschwindigkeits-Zuwachs.

[...]
> Kannst du das mal mit Python testen? Mit und ohne "break".
> Der Vergleich auf deiner Kiste mit dem Ruby-Programm und dem
> Perl-Programm würde mich interessieren:
> 
>     import sys
> 
>     def look_for_begin(stream):
>         for line in stream:
>             if line.startswith("begin"):
>                 print line,
>                 break
> 
>     for filename in sys.argv:
>         look_for_begin(open(filename))
> 

===================================================================
  File "reader.py", line 1
    import sys
    ^
SyntaxError: invalid syntax
===================================================================

Was nu?

"Ich nix Python!" (jedenfalls noch nicht)



[...]
> Außer einem "break" oder "return" fällt mir nur noch eine
> Möglichkeit ein: Vielleicht sorgt irgendeines einer Ruby-Kürzel
> dafür, dass die ganze Datei in ein Array gelesen wird. Glaube
> ich zwar nicht, aber ansonsten ...

Würde mich auch wundern.


> 
> Außerdem solltest du das selbe Programm mehrfach hintereinander
> laufen lassen und die Laufzeit beobachten, um die Auswirkungen
> von Caching-Effekten zu sehen.

Ja, mache ich normalerweise immer, wenn es um etwas mehr als grobes
Abschätzen (Speed-feeling ;-)) geht.


> Und es könnte noch sein, dass
> die Lade-Zeit des jeweiligen Interpreters (Ruby, Perl, Python)
> einen Einfluss hat. (z.B. ist das Perl-Programm vielleicht nur
> deshalb so viel schneller? Nur ne Idee, keine Ahnung)

Naja, würde mich wundern.
Dazu ist der Abstand zu den anderen Progrämmchen zu groß.
Daß Perl und OCaml ähnliche Eregbnisse liefern, und C nicht
massiv schneller ist, das deutet an, daß da irgendwo dann schon
die IO ein Problem ist (langsame Platte).
Aber Ruby war ja auffällig langsamer.
Andererseits war das Ehello world" recht flott.

Aber vielleicht ist beim parsen vom einem einfachen "puts"
wesentlich weniger Ressourcen-Aufwand da als bei dem schon
etwas größeren Scriptchen?!
(So richtig groß isses ja nun nich gerade...)







> 
> Könntest du deine zu scannenden Dateien mal zehnmal durchlaufen
> lassen? Ein paar Sekunden sind aus oben genannten Gründen doch
> noch ein bisschen wenig zum Messen.

Das ist natürlich eine Idee, ja. Hmhhh.

Andererseits sind es 188 Dateien mit ca. 16 MB Größe.
So gesehen sind die 3...4 Sekunden auf der alten HW hier ja auch
kein Problem.

Nicht die Gesamtdauer war ja das Problem, das mir aufstiess,
sondern daß es trotz break/exception/return nicht schneller
wurde!
Bei allen anderen Sprachen war das aber der Fall!


> (d.h. nicht das Programm zehnmal starten, sondern z.B. die
> Dateien zehnmal kopieren, oder jeweils zehnmal als Kommando-
> Zeilen-Argument mit angeben)

Naja, so wenige sind es ja auch nicht.

Aber Du meinst, um mögliche Startup-Effekte heraus zu pfriemeln...?!

Dann könnte ich die Skripte ja alle auch mal auf eine Datei ansetzen
und schauen, was passiert.
Dann müsste doch zumindest das parsen/"compilieren" damit erschlagen sein.

hmhhh.... 0,0<irgendwas> bis 0.1yirgendwas> Sekunden braucht dann Ruby.


Also kann's daran auch niht liegen.

Scheint so, daß Ruby ein purer Interpreter ist?
Perl precompiliert ja on-the-fly und arbeitet dann auf seinem
"compilat" (Pi-Code oder so).

Vielleicht macht ruby das garnicht und arebitet alles interpretativ ab?!


Gruß,
   Oliver



Mehr Informationen über die Mailingliste linux-l