PLZ in einem int speichern?
-
@Gregor: Ups, da kann man ja scrollen.
-
Es ist ganz schön schwer, die Größe eines Strings zu messen. Hier ist mein bescheidener Versuch:
public class TestStringSize { public static void main (String[] args) { if (args.length < 1) return; String [] array = new String [1000]; long memoryOne = 0; long memoryTwo = 0; Runtime runtime = Runtime.getRuntime(); int i = 0; System.gc(); try { Thread.sleep(3000); } catch (InterruptedException e) { } memoryOne = runtime.freeMemory(); for (; i < array.length ; ++i) { array[i] = new String (args[0].toCharArray()); } System.gc(); try { Thread.sleep(3000); } catch (InterruptedException e) { } memoryTwo = runtime.freeMemory(); System.out.println ("String : " + args[0]); System.out.println ("Array-Length : " + array.length); System.out.println ("Free memory before filling array : " + memoryOne); System.out.println ("Free memory after filling array : " + memoryTwo); long memDif = memoryOne - memoryTwo; System.out.println ("difference : " + memDif); long approxSize = (long)Math.round ((double)memDif / (double)array.length); System.out.println ("Approximated size of the String : " + approxSize); } }
Hier das Ergebnis:
gregor@linux:~/JavaProjects> java TestStringSize 12345
String : 12345
Array-Length : 1000
Free memory before filling array : 1942160
Free memory after filling array : 1894448
difference : 47712
Approximated size of the String : 48
gregor@linux:~/JavaProjects> java TestStringSize 123456789
String : 123456789
Array-Length : 1000
Free memory before filling array : 1942152
Free memory after filling array : 1886440
difference : 55712
Approximated size of the String : 56
gregor@linux:~/JavaProjects> java TestStringSize 1234567
String : 1234567
Array-Length : 1000
Free memory before filling array : 1942152
Free memory after filling array : 1886440
difference : 55712
Approximated size of the String : 56Danach sind es also 48 Byte für einen String mit 5 Zeichen und 56 Byte für einen String mit 9 Zeichen. Ein String mit 7 Zeichen kommt aber auch nur auf 56 Byte.
Ich gehe von folgendem aus:
Ich habe bei der Rechnung ein Feld vergessen, nämlich die Länge des Arrays. Das macht 4 zusätzliche Bytes, also insgesamt 46.
Die 2 noch zu klärenden Bytes sind leer und entstehen intern durch ein entsprechendes Alignment. Es wird wohl immer ein Vielfaches von 8 byte belegt. So läßt sich auch erklären, dass Der String mit 9 Zeichen genausoviel braucht, wie der String mit 7 Zeichen.
Weiterhin wurde in den Rechnungen für die Bytegröße offensichtlich aufgerundet (z.B. difference = 55712 -> 56 Byte). Ich geh davon aus, dass hier JVM-intern Speicher freigegeben wurde, der mit dem Programm nichts direkt zu tun hat. Wenn es jemand besser weiß, würde ich gerne davon hören.
Die Werte des Programms werden sich von JVM zu JVM etwas unterscheiden, weil die JVM-Spezifikation nichts darüber aussagt, wie ein Objekt im Speicher repräsentiert werden soll.
-
Ich möcht ja hier kein Flamewar heraufbeschwören, aber hier wäre c/c++ im Vorteil,
da es einfach ascii-Zeichenketten unterstützt.
Du könntest deine Daten ja auch in einer Datenbank speichern, sprich MySQl,Postgres,...
-
SirLant schrieb:
Ich möcht ja hier kein Flamewar heraufbeschwören, aber hier wäre c/c++ im Vorteil,
da es einfach ascii-Zeichenketten unterstützt.
Du könntest deine Daten ja auch in einer Datenbank speichern, sprich MySQl,Postgres,...Ok, in Java kannst du auch ein Byte-Array nehmen. So ist da ja nun auch nicht.
-
Ich möcht ja hier kein Flamewar heraufbeschwören, aber hier wäre c/c++ im Vorteil,
da es einfach ascii-Zeichenketten unterstützt.Wieso ist das ein Vorteil? Ich sehe darin keinen Vorteil, zumal der ASCII Zeichensatz zu allem Überfluss auch noch von der Ländereinstellung abhängt.
Geht es dir um ein Byte Speicher mehr pro Zeichen?Falls es nicht ums Speichern, sondern Laden geht: Genau dafür hat String einen Konstruktor, der ein byte[] annimmt.
-
Nein darum gehts mir nicht, an byte habe ich nicht gedacht. Und die ersten 128
Zeichen sind festgelegt, damit sollte man die Postleizzahlen darstellen können.
Es stellt sich allerdings die Frage wieviel ein 5byte großes byte-Array tatsächlich
benötigt, da bei String ja auch einiges mehr als man annehmen würde benötigt wird.
-
5-Elementiges Byte-Array:
8 Byte Objekt-Overhead
4 Byte Länge
5 Byte Elementemacht 17 Byte.
Zugegeben, es ist immer noch etwas größer. Das ist aber bei Weitem nicht mehr so dramatisch.
-
IMO ist es absolut unbedeutend, da:
50000-Elementiges Byte-Array:
8 Byte Objekt-Overhead
4 Byte Länge
50000 Byte Elementemacht 50012 Byte.
-
@Optimizer: Naja, es kann schon vorkommen, dass man sehr viele kurze Zeichenfolgen benötigt, wie es hier zum Beispiel der Fall ist. In diesem Fall macht der Object-Overhead doch schon einen sehr großen Teil des Gesamtspeicherbedarfs aus.
-
ich wurde auf folgende Idee gebracht, doch mal die toOctalString(int) von der Klasse Integer zu verwenden, dass Ergebnis von mir sieht jetzt wie folgt aus
public String plztostring() { if(stellen ==4) return("0"+Integer.toOctalString(adresse.plz)); else return(Integer.toString(adresse.plz)); }
wobei stellen wie folgt errechnet werden
stellen = (int) (Math.log(plz) / Math.log(10) + 1);
bye
tt
-
Ehrlich gesagt gefällt mir das nicht. Aber das mußt letztendlich du wissen.
Was passiert eigentlich bei der Postleitzahl 09999?
-
Gregor schrieb:
Was passiert eigentlich bei der Postleitzahl 09999?
Ich vermute mal, javac beschwert sich.
Aber mal was anderes: Es geht hier ja um HARTKODIERTE Postleitzahlen. Warum schreibst Du da nicht einfach 1234 statt 01234? Wenn die Eingaben vom User kommen, stoert die fuehrende Null ja nicht.
-
Ich würde den Overhead mit den Strings in Kauf nehmen. Ist doch nicht so schlimm, dafür kann man auch kanadische Postleitzahlen speichern.
Und komfortabel ist String doch.
-
Wer will mir denn ernsthaft erzählen, dass solche Byteknausereien bei heutiger Hardware noch nötig sind ????? Ist doch selbst bei riesigen Mengen von Daten irrelevant.
Mal angenommen du willst 80 Millionen Einträge haben, dann würde dich die String-Variante immer noch "nur" 3,2 GB kosten.