Donnerstag, 19. Juni 2014

Unit Test mit R, ganz einfach

Auch wenn R oft nicht als richtige Programmiersprache gilt, so gibt es auch in R die Möglichkeit Unit Test zu schreiben. Dafür stehen verschiedene Packages zur Verfügung:

  • RUnit
  • testthat
Hier ein minimales Einsteigerbeispiel mit testthat:


source("main/analyzeXltReport.R")
library("testthat")


test_that("Error Rates", {
  xltreport = loadXltXmlReport("test/testreport.xml")
  expect_that( getTranscationErrorCount(xltreport), equals(24) )
  expect_that( getAtionErrorCount(xltreport), equals(24) )
})

Zuerst wird die zu testende Datei geladen und dann das Testframework. Danach ruft man die Testmethode test_that auf mit einem guten Namen und dem eigentlichen Testcode.

Wenn man jetzt den Test ausführt liefert er beim Erfolg kein Ergebnis:
> source('~/git/lhotse-nfa/loadtest/analysis/test/analyzeXltReportTest.R')
> 
Bei Fehlern sieht es dann z.B. wie folgt aus:
> source('~/git/lhotse-nfa/loadtest/analysis/test/analyzeXltReportTest.R')
Fehler: Test failed: 'Error Rates'
Not expected: getTranscationErrorCount(xltreport) not equal to 20
Mean relative difference: 0.2.

Eine kleine Anmerkung, die Pfade in den R Scripten auch im Unit Test beziehen sich auf das aktuelle Directory!

Weitere Informationen zum Unit Testing mit R findet Ihr hier: 


Dienstag, 17. Juni 2014

Python vs. R

Im akademischen Bereich ist R schon lange eine wichtige Konstante wenn es darum geht statistische Auswertungen aka Data Science zu machen (Link). Lange wurde Python wegen seines guten Handlings von Daten als Ersatz für Mainstream-Anwendungen benutzt. Das Datenhandling war ähnlich einfach wie das in R.
R ist im Vergleich zu anderen Programmiersprachen gewöhnungsbedürftig (Link). Auch wenn diese Dinge wie Schleifen vs apply oder der Mangel an graphischen Interfaces (GUI), Blockkommentaren oder Multithreading berechtigt sind, so lässt sich R aber sehr komfortabel als Scriptsprache, wie unter anderem auch Python einsetzen.
Das führt auch  zu einer ständig wachsenden Beliebtheit dieser Sprache wie Redmonk in ihrem Ranking für Programmiersprachen feststellt feststellt (Link). Python schneidet bei diesen Rankings deutlich besser ab. Einen Anteil an der wachsenden Popularität von R hat das gute R IDE RStudio (Link), das abgesehen von der Doppelklick-Select-Word Anomalie sehr zu empfehlen ist.

Kurz zusammengefasst: R ist nicht tot sondern erfreut sich wachsender Beliebtheit und Python sowieso.

Es gibt ein neues Wort im Englischem: Datensparsamkeit

Datensparsamkeit ist nicht erst seit dem NSA Skandal populär. Getrieben durch den CCC und einigen Datenschutzbeauftragten gibt es in Deutschland ein Datenschutzgesetz in dem die Datensparsamkeit als Mittel beschrieben wird.
Jetzt wurde diese Idee geadelt, durch die Übernahme in den Englischen Sprachgebrauch durch Martin Fowler: http://martinfowler.com/bliki/Datensparsamkeit.html

In diesem Sinne, schaut immer aufmerksam auf eure Daten und natürlich auf eure Passwörter.

Mittwoch, 11. Juni 2014

Welche Java GC Version wird benutzt? Oder wie identifiziere ich den Java GC?

Java bietet eine reiche Auswahl an GC Varianten:

  1. SerialGC
  2. ParallelGC
  3. ParallelOldGC
  4. CMS GC
  5. G1 GC
Zusammen mit den möglichen Parametern hat man einen sehr grossen Suchbereich um den optimalen GC mit den optimalen Einstellungen zu finden. GC Optimierungen haften immer etwas mythisches an. Es gibt Supertricks, die bei genauerem Hinsehen und Testen oft überholt sind. Es hilft nur ein ebenes Testsetting aufzubauen und selbst zu messen.
Damit stellt sich die Frage welcher GC wird denn verwendet, ich gebe doch keinen an. Da hilft die Kommandozeile weiter:

java  -verbose:gc -XX:+PrintGCDetails


Das Ergebnis der Konsole ist spezifisch für die entsprechenden GCs.

SerialGC -XX:+UseSerialGC

Es ist ein genrationaler GC mit den drei Generationen: New Generation Tenured Generation und der Perm Generation. Die New Generation teilt sich in die Bereiche Eden, From und To.







ParallelGC -XX:+UseParallelGC

Es ist ein genrationaler GC mit den drei Generationen: Young Generation, Old Generationen Perm Generation. Die New Generation teilt sich in die Bereiche Eden, From und To. Es lässt sich leicht vermuten, dass der ParallelGC eine weiterentwickelte, parallele Variante des SerialGC ist. Es soll durch die Benutzung von allen Kernen die Dauer der GCs verkürzen. Er macht also nur Sinn, wenn man über mehrere CPU-Kerne verfügt.


CMS GC -XX:+UseConcMarkSweepGC

Es ist ein genrationaler GC mit den drei Generationen: Young Generation, Concurrent Mark Sweep Generationen und der Perm Generation. Die New Generation teilt sich in die Bereiche Eden, From und To. 

Der CMS GC basiert auf den Erfahrungen des ParallelGC. Hier werden möglichst viele GC Schritte (Mark, Sweep) parallel ausgeführt ohne ein Stop-The-World auszuführen. Das heisst man kann ungenutzte CPU Kerne für den GC nutzen, wenn man denn welche hat. Der Overhead des CMS GC ist grösser als des ParallelGC aber durch die Benutzung zusätzlicher CPU Kerne wird dieser negative Effekt überkompensiert, so das der CMS bei vilene normalen Anwendungen die Performance der Anwendung verbessert aber die CPU Usage erhöht. Er ist also sinnvoll, wenn ich freie CPU Ressourcen habe. Zusätzlich braucht der CMS immer freien Speicher für seine Operationen. Er kann nicht den ganzen Speicher ausnutzen.

G1 GC -XX:+UseG1GC

G1 GC Details unter Java 7

G1 oder Garbage First ist der zu letzt entstandene GC. Er setzt auf dem CMS GC auf und ändert die Speicherbenutzung für die Young Generation und die folgende Generation, mit dem Ziel die Speicheroperationen zu minimieren und damit die GC Laufzeiten zu reduzieren. Hier teil sich der Speicher in den Garbage First Heap und die bekannte Perm Generation. Der Garbage First Heap kennt da die Unterteilungen in Young und Survivors. Für den G1 GC gelten die selben Performance und Load Anmerkungen wie für den CMS GC, wobei der G1 leicht bessere Werte als der CMS erzielen sollte.

Unter Java 8 wurde der G1 überarbeitet, das hatte zur Folge, dass der Perm Generation jetzt Metaspace heisst.

Fazit

Genereller Tip, der für 80% aller Anwendungen passt. Macht keine GC Einstellungen, lasst sie weg und nutzt die gewonnene Zeit um die Software robuster zu machen. Tipp 2: Setzt die aktuellste Java Version ein. Ein aktuelles Java mit einem neuen GC schliessen viele Optimierungstricks ein, also nur die sinnvollen.
GC Optimierungen bleiben aufwendig. Nur bei High Performance oder High Load Applikationen sind GC Optimierungen sinnvoll. Aber generell gilt immer, zu erste messen, dann optimieren.

Weitere Informationen zum Java GC:

  1. http://www.cubrid.org/blog/dev-platform/understanding-java-garbage-collection/
  2. http://www.angelikalanger.com/Articles/EffectiveJava/27.GCTuning/27.GCTuning.html
  3. http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/G1GettingStarted/index.html

Donnerstag, 3. April 2014

HOWTO: Releasing a new Software Version with Maven and Git.

Ausgangslage:

  • Versionsverwaltung mit Git und Feature Branches
  • Ich befinde mich auf dem Branch development 
  • Alle Fehler auch Javadoc Fehler sind beseitigt
  • Alle Änderungen commitet und gepushed
  • Java
  • Maven 3 und SNAPSHOTS
  • Nexus
Wie mache aus meiner einer aktuelle Entwicklung ein Release?
  1. mvn deploy, um die letzte Development Version als SNAPSHOT im Nexus zu veröffentlichen
  2. mvn versions:resolve-ranges, um Dependencies mit Range Angaben zu konkreten Versioen aufzulösen, sonst scheitert der Release-Vorgang
  3. mvn versions:use-latest-releases, um die Dependencies zu aktualisieren auf deren letzten Release-Stand
  4. git commit, um die Änderungen an der pom.xml in Git Repository zu übertragen
  5. git checkout master
  6. git merge development
  7. mvn release:prepare
  8. mvn release:perform
  9. git commit, um die Änderungen an der pom.xml in Git Repository zu übertragen
  10. git checkout development
  11. git merge master

Das beschreibt den kompletten Weg ein Release zu erstellen vom Development Branch und wieder zurück. Ach ja, und natürlich das Testen nicht vergessen.

Wenn etwas schief geht:

  1. Entfernen von Tags aus Git:
    1. git tag listet alle Tags auf
    2. git tag -d tagname entfernt den entsprechenden Git Tag
  2. Test im Release Prozess wirklich überspringen: mvn release:perform -Darguments="-DskipTests" 

Mittwoch, 26. März 2014

Welche Java Version läuft auf meinem Computer?

Bei dieser Frage ist nicht gemeint, wie ich die Version des aktuell installierten Java abfrage (java -version), sondern was ist dir höchste Version die auf meinem Betriebsystem/Linux läuft? Ich stand vor folgendem Problem, das sich nicht durch ein Betriebssystemupgrade lösen lies:
java -version
Error: dl failure on line 863
Error: failed /var/opt/lhotse-xlt/java/jre/lib/amd64/server/libjvm.so, because /lib64/tls/libc.so.6: version `GLIBC_2.4' not found (required by /var/opt/lhotse-xlt/java/jre/lib/amd64/server/libjvm.so)

Die Version der glibc findet man wie folgt in der BASH heraus:
/lib/libc.so.6
GNU C Library stable release version 2.3.5 (20050720), by Roland McGrath et al.

Damit ergab sich die Frage, welche Java Version läuft mit der glibc < 2.4? Über das Releasedatum des Linux-Kernels bzw. der Linux-Distribution lässt sich die Suche auf eine Java Version reduzieren: Java 6.
uname -a
Linux blade7 2.6.5-7.324-smp #1 SMP Mon Sep 20 15:38:01 UTC 2010 x86_64 x86_64 x86_64 GNU/Linux

Aber die neueren Java 6 Versionen brauch schon die glibc 2.4. Aber über die Oracle Seite (http://www.oracle.com/technetwork/java/javase/system-configurations-135212.html) findet man die korrekte Java Version: Java 6u18.

Montag, 10. März 2014

Anzahl der Java Klassen in einem Projekt zählen

Man sehr einfach mit der BASH die Anzahl der Klassen in einem Projekt zählen. Dazu baut man zuerst ein JAR Datei, z.b. mvn package.  Dann zählt man die die class Einträge in der JAR Datei: unzip -l target/scale-performance-check-1.22.jar | grep .class | wc -l
Es geht auch ein bisschen einfacher: find src/ -name "*.java" | wc -l
Hier werden aber nur die Java Dateien gezählt. Abweichungen entstehen z.B. durch innere Klassen.

Wenn man die LOC zählen möchte kann man dies mit: find src/ -name '*.java' | xargs wc -l
Hierbei werden leere Dateien und Kommentare mitgezählt.