Enumeration/Static Final/Bitfield

teremy

Mitglied
Hallo.

Bin zur Zeit dabei meinen Code etwas zu überarbeiten und da habe ich an vielen Stellen Integers verwendet, obwohl viel kleinere Zahlenbereiche auch reichen, daher verwende ich zum Teil sogar nur noch bytes. Ein anderer Punkt war, dass mir mal jemand sagte, dass Enumerations nicht so effizient sind. Immer wenn ich verschiedene Typen von irgendetwas habe, nehme ich meistens eine Enumeration. Ich habe z.B. für die Blickrichtung eines Spielers Folgendes:
Java:
public enum FacingDirection
{
UP, RIGHT, DOWN, LEFT
}
Der Player besitzt dann eben ein Attribut vom Typ FacingDirection.
Ich frage mich nur wie effizient das ist, also wie wird so eine Enumeration intern repräsentiert?
Letztendlich geht es mir ja nur darum, dass ich da ein Wort reinschreiben kann, was ich verstehe.
Daher hatte ich noch folgenden Ansatz:
Java:
public class FacingDirection
{
	public static final byte UP = 0;
	public static final byte RIGHT = 1;
	public static final byte DOWN = 2;
	public static final byte LEFT = 3;
}
Da ich später Kryonet zur Dateiübertragung nutze, würde mich mal interessieren was nun effizienter ist. Ein Attribut vom Typ FacingDirection oder ein Attribut vom Typ byte.
Selbst 1 Byte ist ja schon zuviel, im Prinzip würden 2 Bit ja auch reichen, sodass UP = 00, RIGHT = 01, DOWN = 01 und LEFT = 11 ist. Intern soll es eben möglichst effizient gemacht werden, mir gehts nur darum, dass ich dem Attribut des Spielers später nicht irgendeine komische Zahl zuweise, sondern dann eben FacingDirection.UP verwenden kann o.Ä... Kann ich ja auch so, nur was ist effizienter?

Des Weiteren habe ich gelesen, dass ein EnumSet intern als Bitvektor repräsentiert wird und es dadurch extrem kompakt und effizient ist ( EnumSet (Java Platform SE 7 ) ).
Macht es Sinn einen Bitvektor irgendwie mithilfe eines EnumSets zu repräsentieren ( was ja intern ohnehin ein Bitvektor ist )? Welche Größe besitzt der Bitvektor dann? Ansonsten würde ich eben eine Klasse Bitvector ( oder so ähnlich ) schreiben die als Attribut einen Integer hat ( ein Integer hat ja 32 Bit ), das wäre dann sozusagen mein Bitvektor, den ich dann mit den Shiftoperatoren und den Operatoren "Und" und "Oder" bearbeiten kann ( da würde ich mir natürlich schöne Methoden schreiben ).

Ich will eben die effizienteste Repräsentation für meine Daten finden, weil ich gerade dabei bin ein Spiel Netzwerkfähig zu machen und Kryonet erlaubt es mir ja ganz einfach Objekte zu senden.

Danke schonmal für eure Zeit!


Jan
 
Vielen Dank für die Antwort, das hat mir schonmal sehr geholfen!
Wenn ich es richtig verstanden habe, wird aus der Enumeration dann eine Klasse erstellt, die als Typ für die einzelnen Elemente der Enumeration genutzt wird ( also intern ).
Als Attribute hat die Klasse einen String ( der Name ) und einen Integer ( die Ordinalzahl ).
Somit müsste meine Variante mit den statischen Byte Konstanten eigentlich effizienter sein. Den Namen kann ich dann zwar nicht unbedingt nutzen, aber das brauche ich auch nicht.

Die EnumSet Geschichte muss ich mir auch nochmal anschauen, aber für meinen Bitvektor werde ich wohl eine eigene Klasse schreiben, die dann mit einem Integer Attribut intern arbeitet, sodass der Bitvektor 32 bit lang ist. Außerdem hab ich lange nicht mehr mit den Shiftoperatoren gearbeitet 🙂.
 
Von der Effizienz her macht es keinen Unterschied, da intern mit dem gleichen Konstrukt gearbeitet wird.

Du kannst es ja mal Profilen.

Enums haben einen handling Vorteil, dass war es aber schon
 
Mit Profilen hab ich mich noch nie beschäftigt, aber werde ich mir mal anschauen.
Die Sache ist, dass ich zur Zeit ein Spiel von mir onlinefähig machen will und für den Netzwerkkram nutze ich KryoNet, was es ja erlaubt Objekte zu verschicken. Grundsätzlich gehe ich davon aus, dass der Speicherplatz eines Objektes von seinen Attributen abhängig ist, daher möchte ich hier natürlich den kleinstmöglichen Dateitypen nutzen und die kleinstmögliche Anzahl an Attributen.
Intern wird bei der Enumeration ja auch noch ein String gespeichert, daher würde ich naiverweise sogar sagen, dass das Objekt später mehr Speicherplatz verbraucht, wenn ich es mit KryoNet verschicke.
Zudem verwende ich bei meinen static finals den primitiven byte Datentyp. Wenn die Enumeration intern einen int verwendet, dann wäre das ja definitiv mehr Speicherplatz. Vermutlich ist die Sache viel komplexer, da KryoNet ja auch noch komprimiert etc., aber vielleicht sollte ich mich dahingehend nochmal informieren, wie KryoNet die Objekte verschickt.
Danke für eure Antworten!
 
Zuletzt bearbeitet:
Enums sind sicherer bezüglich Programmierfehlern.

Scheinbar ist Dir die Effizienz wichtiger als die Korrektheit.

Du kannst aber im Code ein sicheres Konstrukt verwenden und auf dem Übertragungsweg ein effizientes.
 
Du meinst sicher, weil ein byte auch Werte zulassen würde, für die ich gar nichts definiert habe?
Aber sehr gute Idee, ich kann natürlich eine Enumeration verwenden und wenn ich Daten übertragen will, einfach den entsprechenden Wert als byte übertragen und später aus dem byte wieder das Element der Enumeration machen. Das klingt sehr vernünftig.
 

Zurück
Oben