Allheilmittel für Zahlenformate: Strings

Vor inzwischen längerer Zeit, an der Hochschule, führte ich eine Diskussion, in welcher es um das Speichern von Zahlenwerten und die Darstellung von Zahlen ging. Wir wurden uns leider nicht einig.

Aus einer speziellen Datenquelle wurden uns Informationen in Bytes zur Verfügung gestellt. Diese Bytes mussten in einigen Fällen als Ganzzahl interpretiert werden, in anderen Fällen ergaben vier Bytes eine Zahl (siehe dazu auch diesen Beitrag hier), in wieder anderen Fällen waren entweder die einzelnen Bits oder aber High-Nibble und Low-Nibble von Bedeutung. Mein Vorschlag war, in unserer Datenstruktur die Bytes gleich im jeweils interpretierten Zustand zu hinterlegen, also als Int32, oder einfach als Byte bzw. High- und Low-Nibble jeweils in einem eigenen Byte. Das Gegenargument dazu war, dass dann die Repräsentation als Hexadezimal oder als Bit-Array nicht sofort sichtbar sei und es unnötige Code-Dopplung an den Stellen verursacht, an welchen konvertiert werden muss.

Aus diesem Grund wurde eine Struktur geschaffen, die ich an Hand eines abstrakten Beispiels darstellen möchte. Es handelt sich um die Zahl 42, die ich als eben solche in einem Byte gespeichert hätte (einen Überlauf kann es an dieser Stelle nicht geben, soviel sei gesagt).

Das Objekt ermöglicht es mir jetzt, 42 als Integer abzufragen, “42” als Dezimalstring, “0x2A” als Hexadezimalstring oder dann die Bitdarstellung “00101010”.

So wurden anstatt von lediglich einem Byte (effektiv vier Bytes in Java) mehr als 150 Bytes (im Weiteren beziehe ich mich auf diesen festen Wert) belegt, für jeden Wert. Zudem wurden alle Konvertierungen für jedes Objekt ausgeführt, vollkommen unabhängig davon, ob die Werte überhaupt benötigt wurden. Das klingt jetzt an sich nicht so viel, schließlich haben wir ja Tausende von Megabytes zur Verfügung, da fällt ein Objekt ja nicht auf. Dennoch benötigt dieses Objekt mehr als 35 Mal so viel Speicher wie die einfache Lösung.  Und von diesem Objekt wurden im damaligen Fall pro Sekunde ca. 4 Objekte erzeugt und gespeichert. Das bedeutet, nach einer Minute haben wir bereits 240 * 150 Bytes belegt, also  36.000 Bytes statt 960 Bytes. Nach einer halben Stunde Anwendungslaufzeit sind das knapp 1 MB Speicher.

Auch das klingt natürlich eher unwesentlich, jedoch ist das hier an dieser Stelle nur ein einzelnes Objekt. Wenn nun die gesamte Anwendung in ähnlicher Weise gestaltet wird, können Programmabstürze auftreten, da Speicherlecks oder einfach der viel zu hohe Speicherverbrauch die Anwendung abschießen.

Die Moral von der Geschicht’:

Überlegt genau, welche Informationen ihr dauerhaft speichern wollt und welche Informationen nur temporär benötigt werden (z.B. alternative Darstellung von Werten für die GUI). Auch wenn wir heutzutage sehr viele Ressourcen zur Verfügung haben, geht sparsam damit um. Das nachträgliche Ändern von Speicherstrukturen ist wesentlich aufwändiger und schwieriger, als wenn ihr bereits bei deren Entwurf auf den Speicherabdruck achtet.

Leave a Reply

Your email address will not be published. Required fields are marked *