# ein ganzes Array effizient übermitteln



## Ulrikop (6. Aug 2009)

Hallo,
ich habe mir Spaßes halber ein Programm geschrieben, dass Primzahlen findet. Da ich mir dachte, dass es doch sinnvoll wäre, wenn mehr Rechner helfen können, habe ich mir einen Server und einen Client geschrieben. Der Server nimmt Clients an und gibt ihnen immer wieder eine Zahl, die der Client untersuchen soll. Dieser gibt zurück, ja oder nein.
Der Server speichert dann die gefundenen Primzahlen.

Nun dachte ich mir, wenn ich schon sowas baue, will ich nicht irgend wann an die Grenzen der Zahlen kommen (ok, bis ich endlich bei max von long (9223372036854775807) ankommen würde, würde noch ne Zeit dauern aber man ist ja perfektionistisch  ).
Deshalb bin ich nun auf BigInteger gestoßen, die sich gut anhören. Doch wie gebe ich die Zahlen vom Server zum Client? Denke als BigInteger-Objekt immer schicken, würde Leistungstechnisch net wirklich toll sein.
So bin ich darauf gestoßen, dass BigInteger Byte-Arrays von der Zahl machen können und der Konstruktor erlaubt genau ein solches Array auch. Hört sich toll an, ein Byte-Array kann ich auch prima in den Stream stopfen.

Nur, wie lese ich dann ein Byte-Array am besten aus, bei dem man die größe nicht weiß? Gibt es einen Reader, mit dem ich bequem readByteArray oder so aufrufen kann?
mit dem normalen Stream kann ich auch in ein Array lesen lassen. Aber da ich net genau weiß, wie lang es sein wird, müsste ich bei jeder Eingabe eine Schleife laufen lassen.
Weitere Möglichkeit wäre, dass ich erst die Zahl in den Stream schreibe, wie groß der Byte-Array werden wird und dann erst den Array selbst. So weiß ich beim Auslesen, wie groß es werden wird und kann ein dem entsprechend großes Array mitgeben. 

Tut mir leid, wenn es eine Anfänger-Frage ist oder meine Ideen nicht wirklich effizient sind. ich bin leider noch nicht wirklich erfahren.


Vielen Dank für eure Hilfe.

lg~
Ulrikop


----------



## musiKk (7. Aug 2009)

Ulrikop hat gesagt.:


> Weitere Möglichkeit wäre, dass ich erst die Zahl in den Stream schreibe, wie groß der Byte-Array werden wird und dann erst den Array selbst. So weiß ich beim Auslesen, wie groß es werden wird und kann ein dem entsprechend großes Array mitgeben.



Top. Mit [c]InputStream[/c] und [c]OutputStream[/c] geht das recht einfach.


----------



## FArt (7. Aug 2009)

Optimiere nicht zu früh. Es hört sich an, als gehe es hier nicht um viel Netzwerkverkehr. Übertrage einfach die Objekte.
Wenn es meßbare bzw. spürbare Probleme gibt, dann kümmer dich darum, nicht früher. Eine Möglichkeit wäre dann u.U. den Stream durch eine ZIP-Stream zu ersetzen.


----------



## Ulrikop (9. Aug 2009)

hey danke für die antworten



musiKk hat gesagt.:


> Top. Mit [c]InputStream[/c] und [c]OutputStream[/c] geht das recht einfach.


da man ja nicht weiß, wie groß die angabe der arraygröße wird, wie viel bytes diese Angabe braucht, muss man die Angabe ArrayLänge und ByteArray des BigInteger abgrenzen. Ich hab grad mal auf die schnelle einen solchen Vorgang gebastelt und getestet, ob die zahl rüber kommt. Ich dachte mir, ich schreib es mal hier, damit ihr mir für die Zukunft Tipps geben könnt, wie man es geschickter und schöner baut (wie gesagt bin unerfahren aber da ich es wenn gleich besser lernen will, bin ich für jede Kritik dankbar - aus Fehlern lernt man, nur muss man sie wissen  )


```
BigInteger zahl = new BigInteger("99");
		byte[] byteArray = zahl.toByteArray();
		
		int length = byteArray.length;
		for( ; length > 255 ; length -= 255)
			out.write(-1);
		out.write((byte)length);
		out.write(0);
		out.write(byteArray);
		
		length = 0;
		for(int h = in.read(); h != 0; h = in.read())
			length += (h & 0xFF);
		byte[] byteArrayIn = new byte[length];
		in.read(byteArrayIn);
		BigInteger number = new BigInteger(byteArrayIn);
```

hab das kurz in einem Programm untereinander geschrieben, weils nur zum Testen war. natürlich habe ich es nicht nur mit der Zahl 99 probiert, sondern auch mit einer, die ein ByteArray mit über 255 Einträgen hat.





FArt hat gesagt.:


> Optimiere nicht zu früh. Es hört sich an, als gehe es hier nicht um viel Netzwerkverkehr. Übertrage einfach die Objekte.
> Wenn es meßbare bzw. spürbare Probleme gibt, dann kümmer dich darum, nicht früher. Eine Möglichkeit wäre dann u.U. den Stream durch eine ZIP-Stream zu ersetzen.


hm, warum nicht zu früh optimieren? wenn man immer nur mit den einfachen aber langsamen Mitteln baut, kommt man sicher irgend wann in schwierigkeiten. die heutigen Computer sind so schnell, dass das Programm wahrscheinlich schon ziemlich lang ist, wenn man zum Punkt kommt, an dem er für den Nutzer spürbar langsamer wird. Und dann den Fehler zu suchen, stell ich mir zumindest schwer vor.
Außerdem ist das Programm eher nur aus Spaß und Übungszwecken. Es gibt genug Primzahl-Findungsprogramme mit sicher einer zick mal besserem Algorithmus. Deshalb ist es nur ein Programm für mich. Und da ich schon bisschen perfektionistisch bin, freu ich mich zum einen über jede Sache, die ich optimieren kann und zum anderen denke ich deshalb auch, dass ich mir von Anfang bei solchen Dingen angewöhnen sollte, es optimiert anzugehen und die besseren und sinnvollen Wege zu finden (dafür brauche ich erfahrene Leute, die mir den überhaupt zeigen  ).

Aber wenn du denkst, dass es allgemein besser ist (also nicht nur bei dem Programm hier), da nicht so strikt nach dem Gefühl, optimieren zu müssen, dann erklär es mir bitte. Wie oben gesagt, bin unerfahren und über jeden Tipp dankbar. Manchmal ist es vielleicht auch gar net so gut, so ran zu gehen wie ich es mir denke, nur tu ich mir leichter wenn ich es auch versteh warum anders 



Ich habe mir auch gedacht, dass ich dem Client am Anfang wenn er sich einloggt einen Array voll mit den bereits gefundenen Primzahlen zu schicken (also ein Array voll mit BigIntegers) und ihm dann, jede neue gefundene Primzahlen, egal von welchem der suchenden Clients, zu schicken (natürlich wird das schicken zurückgehalten, wenn es nicht sicher ist, dass es von der Reihenfolge die nächte Primzahl ist).
Somit würde der Client bis zur letzt gefundenen Primzahl nicht mehr durchprobieren müssen.
Nun ist meine Überlegung, wie schicke ich das Array am Anfang? würdet ihr hier nun das Objekt schicken, per zip-stream oder das ganze wie oben aufziehen?



nochmals vielen dank für eure hilfe


----------



## musiKk (9. Aug 2009)

Ulrikop hat gesagt.:


> da man ja nicht weiß, wie groß die angabe der arraygröße wird, wie viel bytes diese Angabe braucht, muss man die Angabe ArrayLänge und ByteArray des BigInteger abgrenzen.



Ja, mein Fehler. Ich glaube, ich habe den Post zig mal überarbeitet, bevor ich ihn abgeschickt habe und dabei die Klassennamen durcheinander gebracht. Die Streams, die ich gepostet habe, sind ja die absolut einfachsten, die sowieso Grundlage für Streamverarbeitung sind.

Ich meinte eigentlich [c]DataInput[/c] und [c]DataOutput[/c]. Dort gibt es [c]writeInt()[/c] und [c]readInt()[/c] und die üblichen read- und write-Methoden für Byte-Arrays. Dadurch kann die Länge ganz bequem geschrieben und gelesen werden. Außerdem habe ich mich derletzt mit [c]readFully()[/c] angefreundet.


----------



## objcler (12. Aug 2009)

> hm, warum nicht zu früh optimieren? wenn man immer nur mit den einfachen aber langsamen Mitteln baut, kommt man sicher irgend wann in schwierigkeiten. die heutigen Computer sind so schnell, dass das Programm wahrscheinlich schon ziemlich lang ist, wenn man zum Punkt kommt, an dem er für den Nutzer spürbar langsamer wird. Und dann den Fehler zu suchen, stell ich mir zumindest schwer vor.



Donald Knuth made the following statement on optimization:
"We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil."


----------



## Ulrikop (12. Aug 2009)

hehe, ja danke. muss ich mir merken 

 knuth mag ich eh


----------

