Star

Benchmark

Ablauf

Alle Logging-Frameworks wurden so konfiguriert, dass Log-Einträge mit dem Level Info oder höher in eine Log-Datei ausgegeben werden. Für Trace- und Debug-Log-Einträge wurde die Ausgabe deaktiviert. Nach jedem Benchmark-Durchlauf werden die Log-Dateien automatisiert auf Vollständigkeit und Korrektheit überprüft.

Das Ausgabeformat entspricht: Datum [Thread] Klasse.Methode(): Text

Für alle Logging-Frameworks, die Methoden zur asynchronen Ausgabe von Log-Einträgen bereitstellen, wurde diese ebenfalls getestet. tinylog nutzt dazu den Writing-Thread, Log4j 1 und Logback einen asynchronen Appender und Log4j 2 die von den Entwicklern empfohlenen asynchronen Loggers. Bei asynchroner Ausgabe erfolgt das Schreiben in die Log-Datei gepuffert.

Jeder Benchmark wurde für jedes Logging-Framework 120 mal ausgeführt. Dabei wurde für jeden Durchlauf eine neue, unabhängige JVM gestartet. Die 10 besten und 10 schlechtesten Durchläufe wurden herausgerechnet, damit Ausreißer nicht das ganze Ergebnis verfälschen. Das Endergebnis entspricht dem Durchschnittswert der übrigen 100 Durchläufe.

Umgebung

Alle Benchmarks wurden auf einem Intel Core i7-4790 (3,60 GHz Vierkernprozessor) mit 16 GB Arbeitsspeicher unter Windows 7 (SP1) mit JRE 8u151 ausgeführt.

Folgende Logging-Frameworks wurden getestet:

Maximal möglicher Output

In diesem Benchmark wird gemessen, wie schnell die einzelnen Logging-Frameworks Log-Einträge ausgeben können. Der Benchmark macht nichts anderes, als in einer Schleife eine Million mal Log-Enträge mit den Leveln Error, Warning, Info, Debug and Trace zu erzeugen.

tinylog
mit Writing-Thread
 2 s 483 ms
 1 s 256 ms
JUL
 6 s 982 ms
Log4j 1
mit Async-Appender
9 s 989 ms
 6 s 79 ms
Logback
mit Async-Appender
11 s 531 ms
 7 s 496 ms
Log4j 2
mit Async-Logger
18 s 354 ms
 8 s 840 ms

Einfluss auf rechenintensive Anwendung

Noch wichtiger als der maximal mögliche Output dürfte in der Praxis sein, wie sich Logging auf die Performance der eigentlichen Anwendung auswirkt. Dies wird in einem zweiten Benchmark getestet, der alle Primzahlen von 2 bis 10.000.000 berechnet. Dabei werden mit 16 Threads alle Kerne voll ausgelastet. Jede gefundene Primzahl wird als "Info" geloggt und alle Nicht-Primzahlen als "Trace" verworfen.

tinylog
mit Writing-Thread
 3 s 43 ms
 1 s 275 ms
Logback
mit Async-Appender
 4 s 519 ms
 3 s 652 ms
Log4j 2
mit Async-Logger *
 6 s 18 ms
 4 s 90 ms
JUL
12 s 59 ms
Log4j 1
mit Async-Appender
16 s 218 ms
9 s 309 ms

* Log4j 2.10 hat ein oder zwei Log-Einträge in 5 von 120 Durchläufen verloren. Dies ist reproduzierbar, ist aber in früheren getesteten Versionen von Log4j 2 nicht aufgetreten.

Fazit

tinylog kann sich in beiden Benchmarks gegenüber anderen Logging-Frameworks klar behaupten. Durch asynchrone und gepufferte Ausgabe von Log-Einträgen kann die Logging-Performance deutlich gesteigert werden. Dies ist allerdings mit dem Nachteil verbunden, dass beim Absturz der JVM die letzten - und damit die wichtigsten - Log-Einträge verloren gehen können.

Das Benchmark-Programm ist auf GitHub als Open-Source verfügbar. So können die Ergebnisse selbst nachvollzogen werden. Die Parameter der Benchmarks, wie beispielsweise das Ausgabe-Format für Log-Einträge oder die Stack-Trace-Tiefe, können an eigene Anforderungen angepasst werden.