PLZ in einem int speichern?



  • Höh??

    Zum Interpretieren von einer POSTLEITZAHL braucht man doch so oder so FÜNF Stellen!! Und wenn man dann nachher beim Auslesen was wie 3295 rausbekommt, WEISS man, daß es eigentlich 03295 heissen muß! 😕


  • Mod

    Sgt. Nukem schrieb:

    Zum Interpretieren von einer POSTLEITZAHL braucht man doch so oder so FÜNF Stellen!! Und wenn man dann nachher beim Auslesen was wie 3295 rausbekommt, WEISS man, daß es eigentlich 03295 heissen muß! 😕

    Ich weiß ehrlich gesagt nicht, ob es auch Postleitzahlen mit weniger Stellen gibt. Wenn nicht, dann hast du natürlich recht.


  • Mod

    So, meine String-Rechnung da oben war etwas falsch. Hier kommt die richtige Rechnung:

    Ich nehme einen String mit 5 Zeichen an.

    1. die 5 Zeichen benötigen 10 Byte, da es sich um "char" handelt, also Unicode-Zeichen.

    2. Das char-Array, welches intern gespeichert wird, muss referenziert werden. Ich gehe hierbei von 4 Byte für die Referenz aus. Weiterhin wird das char-Array vermutlich selbst einen gewissen "Object-Overhead" mitbringen.

    3. Jedes Objekt der Klasse String besitzt 3 weitere private Variablen:
    private int offset;
    private int count;
    private int hash;

    Das macht 12 zusätzliche Byte.

    4. Es kommt der "Objekt-Overhead" hinzu. Ich tippe hier auf etwa 8 Byte. Genaues weiß ich momentan nicht, aber 8 Byte ist der Wert, den ich in Erinnerung habe.

    Macht also

    10 + 4 + 8 (Char-Array-Objekt-Overhead) + 12 + 8 = 42.

    Ein String mit 5 Zeichen braucht also vermutlich 42 Byte. Dabei existiert noch keine Referenz auf diesen String. Pro Referenz auf den String kommen vermutlich 4 weitere Bytes hinzu.


  • Mod

    Da sieht man mal, wie schnell man sich bezüglich der Größe von etwas täuschen kann. Ich wollte zuerst auch posten, dass sich die beiden Varianten bezüglich der Größe fast nicht unterscheiden. Letztendlich ist ein Faktor > 10 als Unterschied herausgekommen. ...äußerst interessant.



  • Ein Zeichen entspricht immernoch einem Byte.
    Also insgesamt 5 Byte.



  • Und wenn man dann nachher beim Auslesen was
    wie 3295 rausbekommt, WEISS man, daß es
    eigentlich 03295 heissen muß!

    das mag schön und gut sein es kommt aber nicht sowas raus, bsp. plz 06122 die Zahl die mir Java präsentiert ist 3154
    dann mal weiter spekuliert, wäre eine postleitzahl wie 01229 existent bringt mir java einen integerüberlauf, wenn eine Zahl wie 01220 existieren würde dann käme eine zahl mit 3 stellen raus...
    aber das positive ist PLZ scheinen alle bei 1 am ende zu beginnen, nur was passiert wenn der user ausversehen eine falsche plz eingibt? anstatt es falsch abzuspeichern können die lustigsten sachen passieren, wie zb. das mit dem int overflow

    bye

    tt


  • Mod

    xy schrieb:

    Ein Zeichen entspricht immernoch einem Byte.
    Also insgesamt 5 Byte.

    In Java nicht. Du scheinst dich mit Java nicht auszukennen. Vielleicht solltest du dann nicht irgendwelche Behauptungen posten.



  • @Gregor

    Ich glaube du solltest mal da öfter nachschauen, bevor du hier son Müll erzählst.

    http://www.selfjava.de/java0107.htm#String



  • Ja, bitte? Was willst du uns mit diesem Link sagen? Dass String einen Konstruktor hat, der aus einem Byte-Array einen String erstellt?


  • Mod

    @Optimizer: Scroll mal etwas hoch! Da steht tatsächlich, dass ein char ein Byte umfaßt. Es ist aber trotzdem falsch. Ein char umfaßt 2 Byte in Java.



  • Sting ist ne Klasse und Gregor hat die Grösse der Speicherbedarfs von Stings errechnet, da ja in der Klassen verschiedene private Members gibt, bedeutet das ein Sting mit fünf Zeichen größer sein muss.

    und wenn ich mich richtige erinner ist jedes Zeichen ein Unicode damit verbraucht es 2 Byte. 5 x 2 = 10 Byte plus die Klassenmebers summe siehe Gregor Post

    ups ich sehe Gregor hat alles richtig Dargestellt.


  • Mod

    Hier ist mein Link:

    Java Language Specification - 4.2.1. Integral Types and Values

    For char, from '\u0000' to '\uffff' inclusive, that is, from 0 to 65535

    Man kann sich leicht ausrechnen, dass dies gleichbedeutend mit einer Größe von 2 Byte für ein char ist.



  • Es ist so oder so suboptimal. Je nach Land besteht eine PLZ nicht wirklich nur aus Zahlen. (Canada hat z.B. Buchstaben drin)

    -junix



  • @Gregor: Ups, da kann man ja scrollen. 😉


  • Mod

    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 : 56

    Danach 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,...


  • Mod

    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.


  • Mod

    5-Elementiges Byte-Array:

    8 Byte Objekt-Overhead
    4 Byte Länge
    5 Byte Elemente

    macht 17 Byte.

    Zugegeben, es ist immer noch etwas größer. Das ist aber bei Weitem nicht mehr so dramatisch.


Anmelden zum Antworten