Java-Notizen

29. Dezember 2021

 

foto Dieser Tage ist endlich mal Zeit, die Dokumentation der Neon-Module zu vervollständigen. Dabei fällt der Größenunterschied auf, der mit dazu beitrug, dass Neon mit seinen Modulen entstand.

Ich hatte mich oft gefragt, warum es keine Sammlung von Funktionen gibt, die so einfache Aufgaben erfüllt wie das Kopieren oder Verschieben von Dateien. Ich kenne eigentlich nur die Klassenbibliothek Apache Commons IO, aber allein die Klasse FileUtils darin hat schon an die 50 KB. Die gesamte Bibliothek kommt auf sage und schreibe 4,5 MB.

Größe

Vieles davon braucht man selten bis nie, aber es gibt keine Möglichkeit, nur den Teil zu nutzen, den man braucht. Das Beispiel mit den FileUtils zeigt, dass selbst die benötigten Funktionen oft unnötig groß ausfallen. Meine eigene Klasse FileManager kommt mit 25 KB gerade mal auf die Hälfte und da sind sogar noch die Bindungen ans HTTP-Protokoll enthalten, die ich irgendwann mal noch separat fassen möchte.

Hier zeigt sich die verbreitete Unsitte, immer alles denkbare in eine Software zu verpacken anstelle die einzelnen Funktionen modular auseinander zu halten. Einige weitere Beispiele:

Die Liste ließe sich noch weiter fortsetzen und immer ist das Argument, man könne das nicht vergleichen, weil die großen Funktionssammlungen ja mehr können. Richtig ist, dass sich beim Blick auf einzelne Funktionen bereits die Ineffizienz zeigt.

Abhängigkeiten

Vielleicht bestes Beispiel: Die Klasse MultipartStream in der Klassenbibliothek FileUpload modelliert den Umgang mit multipart/form-data, wie es bei Dateiuploads gebräuchlich ist. Mehr als diese Klasse braucht es für Uploads nicht und dennoch ist die Klassenbibliothek 2,5 MB groß.

Die Klasse MultipartStream lässt sich auch nicht ohne weiteres herauslösen und einem Programm eigenständig mitgeben, weil in der Version von Apache zahlreiche unnötige Abhängigkeiten eingebaut sind. Erst mit einer kompletten Überarbeitung der Klasse, wie sie in das Modul http-up eingeflossen ist, gelingt das und siehe da: Die Upload-Funktion ist für gerade einmal 22 KB zu haben. Das ist weniger als ein Hundertstel (!).

Ein weiteres beliebtes Argument der Verfechter solcher unnötig großen Klassenbibliotheken ist, dass zur Laufzeit ja immer nur die wirklich benötigten Klassen geladen werden. Das stimmt aber ebenfalls nicht, weil das Beispiel mit FileUtil zeigt, dass wesentliche einzelne Klassen bereits das Dopppelte des Nötigen oder mehr 'auf die Waage' bringen.

Zudem führen unnötige Abhängigkeiten wie bei FileUpload dazu, dass für eine benötigte Klasse stets ein ganzes Geflecht von Klassen in den Speicher geladen werden muss, was Rechenleistung und Speichereffizienz unnötig verschlechtert.

Fazit

Alles in allem führt das zum Ruf von Java-Anwendungen, zu schwerfälligen, riesig monolithischen Speichermonstern zu geraten. Mit Blick auf die obigen Beispiele wie auch auf wahnwitzige Konstrukte wie die Java Persistence API, Java Web APIs oder das Spring Framework stimmt das leider auch.

Das ist aber nicht charakteristisch für die Java Technologie sondern nur das Ergebnis des falschen Designs. An Produkten wie Neon und dessen Modulen ist ersichtlich, dass die Java Technologie extrem effizient genutzt werden und dabei vermeintlich modernere Plattformen noch immer in den Schatten stellen kann.





 

Copyright © Ulrich Hilger, alle Rechte vorbehalten.