Simple Benchmarks mit JUnit

Im Java Umfeld wird die Performance einer Implementierung gerne vernachlässigt.
Wer muss denn auch schon darüber nachdenken, ob eine ArrayList oder LinkedList für ein Problem besser geeignet ist. Vor allem, wenn nur ein paar 1000 Objekte gespeichert werden müssen?
Und selbst wenn man sich Gedanken über die Performance macht… wie trifft man denn überhaupt zuverlässige Aussagen darüber, wie schnell eine Implementierung tatsächlich ist?

Ein einzelner Test ist alles andere als aussagekräftig und auch das Testen mit Stoppuhr wird zwar oft betrieben, sagt aber eigentlich nicht sehr viel über die Performance aus. Schließlich hängt die Performance von sehr vielen Faktoren ab und kann sich zwischen mehreren Testläufen auch unterscheiden. Trotzdem gibt es im Java-Umfeld nicht gerade viele Tools, die sich mit solchen Tests beschäftigen.

Die bekanntesten Tools im Java-Umfeld sind wohl Apache JMeter und auch Grinder. Doch beide Tools zeichnen sich nicht gerade durch Einfachheit aus. Auch wenn es für beide Tools ein Jenkins-Plugin gibt, so sind beide nicht das, wonach ich suche.

Zwei weniger bekannte Tools zum Testen sind JUnitBenchmarks und ContiPerf. Ihr Funktionsumfang ist deutlich geringer als jener von JMeter und Grinder (beispielsweise gibt es keine Unterstützung für das Testen von Webservern über HTTP), jedoch zeichnet beide Tools eine enorme Einfachheit aus. Einfach der JUnit 4.x Testklasse eine Rule hinzugefügt (eine annotierte Member-Variable) und schon hat man seinen ersten Performance-Test. Konfigurierbar sind beide Tools über Annotations, was ebenfalls zur Einfachheit beiträgt.
Etwas schlechter sieht es hingegen bei der Unterstützung durch Jenkins-Plugins aus. Beide Tools erstellen schöne HTML-Reports, sind aber nicht problemlos in Jenkins einzubinden (ok, man kann natürlich die Reports im Jenkins-Arbeitsbereich einsehen, aber ein Trend-Graph oder ähnliches ist halt schon eine tolle Sache). Glücklicherweise gibt es allerdings das Performance-Plugin, welches zumindest die Gesamtlaufzeit der JUnit-Tests messen kann, womit man zumindest einen Trend-Graph über die Gesamtlaufzeit erhalten kann. Da man bei den Tools einen InvocationCount mitgeben kann (und nebenbei auch noch eine WarmUp-Phase berücksichtigen kann) sind die Testergebnisse aber zumindest ziemlich aussagekräftig.
Für die Zukunft bleibt zu hoffen, dass die Tools eine bessere Integration in Jenkins erhalten, um damit Java-Projekte noch besser entwickeln zu können. Ich persönlich habe mich derzeit für ContiPerf entschieden, denn erstens scheint es ausgereifter zu sein (in JUnitBenchmarks haben bei mir einige Class-Annotations nicht funktioniert) und andererseits gibt es mehr Einstellungen, die man per Annotation beeinflussen kann (man kann beispielsweise nicht nur angeben, wie oft ein Test ausgeführt werden soll, sondern auch, dass gemessen werden soll, wie oft der Test in 20sec durchläuft)

2 Gedanken zu „Simple Benchmarks mit JUnit“

  1. Wie in einem kleinen Follow-Up berichtet, bietet TestNG die Funktionalität von ConitPerf ohne weitere Libraries ab. Will man also eine derartige Performance-Messung umsetzen, so sollte man überlegen ob man nicht lieber JUnit durch TestNG ersetzt.

Schreibe einen Kommentar