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:
- tinylog 1.2
- JUL (java.util.logging.Logger)
- Log4j 1.2.17
- Log4j 2.10
- Logback 1.2.3
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 |
|
---|---|
JUL | |
Log4j 1 mit Async-Appender |
|
Logback mit Async-Appender |
|
Log4j 2 mit Async-Logger |
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 |
|
---|---|
Logback mit Async-Appender |
|
Log4j 2 mit Async-Logger * |
|
JUL | |
Log4j 1 mit Async-Appender |
* 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 -
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.