Freitag, 26. November 2010

Optimierung von Endrekursionen in Java

In meinem letzten Post (Funktionale Programmierung mit Java) musst ich noch zugeben, dass ich nicht wusste ob Java Optimierungen von Endrekursionen (Tail Recursion) beherrscht. Nach einem kleinen Test, kann ich sagen, das Java 1.6 diese Optimierung beherrscht. Getestet habe ich mit:

java version "1.6.0_22"
Java(TM) SE Runtime Environment (build 1.6.0_22-b04-307-10M3261)
Java HotSpot(TM) 64-Bit Server VM (build 17.1-b03-307, mixed mode)


Der optimierte Code läuft um den Faktor 4 bis 5 schneller. Dies ist enorm! Beim Code handelt es sich um eine modifizierte Version von Blackflash (Andre Mölle). Andre Mölle vergleicht funktionale Programmierung in Java und anderen Programmiersprachen mit und ohne Endrekursionen (Link). Bei ihm gab es keine Unterschiede zwischen optimiertem und nicht optimiertem Code. Was aber an verschiedenen Dingen liegen kann. Mein Ergebnis steht damit im Widerspruch zu dem Ergebnis von Andre Mölle aus dem Jahr 2008. Man kann diese Unterschiede mit verschiedenen Versionen der Java VM/Compiler begründen. Leider habe ich kein passendes Dokument von Sun/Oracle zu diesem Thema gefunden.

Funktionale Programmierung mit Java

Java zählt zu den imperativen Programmiersprachen, wie die meisten verbreiteten Programmiersprachen. Was ich beim schreiben von Java-Methoden anstrebe, ist die Vermeidung jeglicher Seiteneffekte, d.h. eine Methode benutzt nur die Übergabeparameter. Dies erhöht erheblich die Verständlichkeit und die Wartbarkeit des Codes. Damit kann man solche Methoden als statisch deklarieren. Damit bezieht sich Methode nicht mehr auf Objekt sondern auf die Klasse. Damit könnte man die Methode auch an einen beliebigen Ort verschieben, davon rate ich im Allgemeinen ab, weil dies der Verständlichkeit des Codes abträglich wäre. Ich nenne diese Art der Programmierung neoprozedurale Programmierung. Beim Einhalten dieses simplen Paradigmas wird man sehen, dass sich sowohl der Code als auch die Denkweise des Programmierers sich positiv verändert. Wenn man bei Webservices den Transportaspekt vernachlässigt, dann erinnert die neoprozedurale Programmierung an die Webservice-Idee. Wenn man dann die neoprozedurale Programmierung mit dem Test-Driven-Programming kombiniert, kommt man der funktionalen Programmierung schon näher. Aber funktionale Programmierung ist mehr. Ein leichte, praktische Einführung gibt im Blog von Alexander Pohl N blog N. Was für ein toller Name für ein Blog, ich bin neidisch, das so ein Name nicht auch mir eingefallen ist. Welche Frage ich mir stelle, ist die funktionale Programmierung ein Ziel der agilen Softwareentwicklung? Ich höre jetzt die HASKELL-Programmierer schon lästern. Und die Java- und C-Programmierer werden schimpfen über die Verschwendung von Speicherplatz (Ups, Stack Overflow: also -Xss benutzen) und Rechenzeit, wenn man Schleifen durch Rekursionen ersetzt. Dem kann ich natürlich die Optimierung von Endrekursionen (Tail Recursion) entgegenhalten, allerdings weiss ich nicht ob Java (Compiler, JVM) solche Optimierungen macht. Ich bin mir nicht ganz sich, was der aktuelle Stand bei Java ist, aber es steht bei OpenJDK (Da Vinci Machine) auf dem Plan (Link). Ich bin gespannt, wie es weitergeht. Ich würde mir wünschen, Java in eine Art funktionalen Compiler-Modus zu versetzen um in Java funktional zu programmieren.

Donnerstag, 25. November 2010

Au weia, ich habe die falsche Datei überschrieben ...

was nun, ich habe eine wichtige Datei im Projekt überschrieben und im Subversion liegt auch nur eine alte Version. Eclipse liegt lokale Kopien von den Daten an die man bearbeitet. Wenn man eine solche lokale Kopie wiederherstellen will, muss man im Package Explorer einen Rechtsklick auf die Datei machen und dann in das Menü Restore from Local History ... (siehe Bild).
Damit hat man das erste Problem gelöst, aber da hinter jedem kleinen Problem ein grosses Problem steckt, muss auch dieses Problem gelöst werden. Es zeigt sich also, dass die Richtlinien fürs Codemanagement unvollständig sind oder unzureichend umgesetzt werden. In der Regel gilt, nach jeden Bug Fixing, nach jeden Feature oder nach jedem Refactoring sollte das SVN Repository aktualisiert werden. Übrigens kann man auch sehr einfach ein lokales SVN aufsetzen (Setup a Subversion Server in 4 Minutes). Wenn sich dies nur schwierig im eigenen Entwicklungsprozess umsetzen lässt, dann sollte man einen Blick auf Git werfen.