Wettlauf der Compiler

Der Fefe macht etwas (für mich) interessantes und sammelt Code in verschiedenen Sprachen für ein simples Problem:

Die Aufgabenstellung ist: stdin lesen, in Wörter splitten, für die Wörter dann jeweils die Häufigkeit zählen, am Ende die Wörter mit Häufigkeiten nach letzteren sortiert ausgeben.

Außerdem fordert er, dass der Code relativ natürlich für die jeweilige Sprache ist, also so, wie man ihn normalerweise, also ohne Wettbewerb, auch schreiben würde. Mitmachen ist erwünscht, so kann jeder Code in einer beliebigen Sprache einreichen.

Damit vergleicht er natürlich hauptsächlich die Implementierungen, wobei sich da mit der Zeit wohl halbwegs sprachoptimale Lösungen einfinden werden. Dann bleibt wohl der Wettstreit von einerseits Sprachkonzepten, andererseits aber auch der Qualität von Compilern und Interpretern. Aktuell steht es so:

  Implementation	Mem/MB	Time

  C++/Boost		381	7.36s user 1.55s system 99% cpu 8.921 total
  C++ (g++ 4.3.2)	390	11.30s user 0.35s system 100% cpu 11.653 total
  C (gcc 4.3.2)		171	12.78s user 0.24s system 99% cpu 13.022 total
  Java 1.6.0_11		56	14.88s user 0.18s system 100% cpu 14.963 total
  Perl 5.10.0		578	14.87s user 0.49s system 100% cpu 15.360 total
  PHP 5.2.7		398	22.79s user 1.71s system 98% cpu 24.793 total
  C# (mono 2.0.1)	498	25.53s user 3.12s system 99% cpu 28.749 total
  sh				25.63s user 1.43s system 100% cpu 27.011 total
  OCaml 3.11.0		414	27.30s user 0.53s system 99% cpu 27.837 total
  Python 2.6.1		529	27.47s user 0.38s system 100% cpu 27.849 total
  Lua 5.1.4		1293	30.44s user 1.44s system 99% cpu 31.900 total
  Tcl 8.5.5		1917	41.31s user 2.07s system 99% cpu 43.388 total
  Ruby 1.9.1preview1	537	54.10s user 0.32s system 99% cpu 54.439 total
  Scheme (MZ 4.1.3)	948	60.50s user 1.91s system 99% cpu 1:02.46 total
  Java (gcj 4.3.2)		72.98s user 0.39s system 99% cpu 1:13.38 total
  Ruby 1.8.7pl72	643	80.57s user 0.39s system 99% cpu 1:21.02 total
  Haskell (ghc 6.10.1)	1450	50.34s user 0.74s system 99% cpu 51.112 total
  mawk 1.3.3		225	135.40s user 0.67s system 100% cpu 2:16.05 total

Nicht sehr überraschend ist, dass Skriptsprachen tendenziell hinter kompilierten Sprachen zurückbleiben, wobei sich Perl sehr stark zeigt – mit riesigem Speicherbedarf.

Interessant finde ich aber, dass der gcj so weit hinter der Maschine von Sun zurückbleibt und auch, dass für C++ anscheinend zwar eine sehr schnelle, aber auch relativ speicherintensive Implementierung gefunden wurde, wobei Java, nun ja, nicht nennenswert schlechter als C(++) ohne Boost ist, aber anscheinend seinen Speicher sehr gut im Griff hat. Da die Implementierungen aber per se nicht direkt vergleichbar sind, bleibt abzuwarten, was sich da noch so entwickelt.

Was mich noch interessieren würde, wäre weniger die Laufzeit für eine große Eingabe, sondern wie sie sich für verschieden große Eingaben verhält.

2 Comments.

  1. Ob der Günther wohl Smalltalk einreichen wird? :)

  2. Nein, wird er nicht. Das klassische Smalltalk hat ohnehin keinen Zugriff auf die Standardeingabe, mal ganz davon abgesehen dass der Quelltext üblicherweise nicht in Textdateien kommt. :-)

    Es würde so oder so ähnlich aussehen:

    | b |
    b := Bag new.
    self eachLine: [ :line |
    (line subStrings: ' ') do: [ :word | b add: word. ].
    ].
    ^b sortedElements.

    Davon abgesehen fehlt nun nur noch die Implementierung der Methode eachLine:, die die Strings aus dem Stream pulen muss.