memcpy



  • das ist ja wesentlich langsamer als ein memcpy, da das memcpy in C++ ja asembleroptimiert ist

    Java muß doch auch solche Funktionalitäten bieten?

    MfG



  • ich schildere mal mein Problem genauer

    Ich habe einen Puffer:

    byte[] b = new byte[1000]
    

    Jetzt habe ich eine Funktion PutData(byte[] rgubData) wobei die Daten so zwischen 10 und 100 Bytes aus oben genanntem Puffer sind.

    Wenn ich jetzt rgubData.length mache hat der ja dann immer 1000 und nicht die tasächliche Länge. Normalerweise macht er ja beim Aufruf der Funktion eine Kopie der Variable, kann man dem Java sagen er soll nur eine Kopie von soundsoviel Bytes machen?

    MfG



  • Ich weiß auch nicht was passiert wenn ich das mache

    byte[] b = new byte[1000];
    byte[] c = new byte[10];
    
    c = b;
    PutData(c);
    c = null;
    

    Ich vermute er gibt einfach den Speicher von c wieder frei und überschreibt den Zeiger?

    MfG



  • Destiniy schrieb:

    Normalerweise macht er ja beim Aufruf der Funktion eine Kopie der Variable

    Kopien werden nur bei primitiven Typen erstellt. Ein Array ist kein primitiver Typ mehr, sondern eine Klasse. Folglich wird nur eine Referenz auf das Array übergen und nicht sämtliche Werte kopiert.



  • Die Methode heißt arraycopy() und ist in der Klasse System.
    In der Regel ist es aber üblich einfach neben dem Array noch einen Parameter length mitzugeben, der angibt, wieviel aus dem übergebenen Array gelesen werden soll, siehe z.B. die read() Methoden in I/O Klassen. Ist auch schneller als die Daten zu kopieren. :schland:



  • Servus,

    du arbeitest dich gerade in Java ein oder schreibst zumindestens ein paar Codezeilen um 😃

    Daher bitte ich dich, erstmal die Grundlagen von Java zu lernen und anzuwenden. (bitte nicht falsch verstehen, ist nicht böse gemeint)

    das ist ja wesentlich langsamer als ein memcpy, da das memcpy in C++ ja asembleroptimiert ist

    Erstmal ist memcpy kein C++! Du meinst eher C 😕
    Du stellst hier eine Behauptung auf, die du nicht belegt hast. Du solltest doch wissen, dass man erst einmal eine Lösung sucht und erst wenn beim Test diese Lösung zu langsam ist werden nach alternativen gesucht.

    Die Java-Library ist wesentlich schöner und eleganter umgesetzt wie in der C-Familie. Ist wurde viel mehr Wert auf OOP gelegt als auf Funktionen.

    Achja, damit es ein Flameware wird.
    Geschwindigkeitsvergleich: Java <=> C++
    Beide Technologien/Sprachen stehen sich nichts mehr nach. Es kommt auf dem Anwendungsfall an. Je nach Microbenchmark schneidet mal der mal der andere besser ab. Java hat halt noch den schlechten Ruf aus den 90er. Aber das ist seit langem Vergangenheit.
    Bei nvidia.com gab's mal ein paar schöne Benchmarks in OpenCL Sektor. Leider finde ich diese nicht mehr 😞

    Jetzt habe ich eine Funktion PutData(byte[] rgubData) wobei die Daten so zwischen 10 und 100 Bytes aus oben genanntem Puffer sind.

    Es ist zwar egal, aber woher kommen die Daten?
    Wahrscheinlich von einem Stream. File, Socket, ... egal. Möchtest du einen Buffer vorschalten, kannst du einen BufferedInputStream(inputStreamVariable) erzeugen. Von diesem ließt du danach die Daten ein. Die Buffer regelt Java im Hintergrund selber 🙂
    Die Sun-JVM ist sehr stark auf int und double optimiert worden. Daher sollte man diese Datentypen bevorzugt verwenden.
    Von dem BufferedInputStream kannst du jetzt mit

    int[] buf = new int[100]
    int len = 0
    while((len = bufInput.read(buf)) > 0 ) {
      // len beinhaltet die Länge der gelesenen Daten
      // Hier im Beispiel: 0 <= len < 100 wobei die 0 von der Schleife ausgeschlossen wird
    }
    

    Ließ doch bitte mal dieses Buch 👍



  • Achja, ob wohl int[] verwendet wird ließt du nur bytes ein



  • ja ich arbeite mich gerade in Java ein

    ich habe hier ein Buch (Handbuch der Java Programmierung mit 1300 Seiten) aber ich weiß nicht so recht wo ich anfangen sollte. Also hab ich einfach mal ein Anwendung angefangen und schue immer im buch nach falls sich fragen ergeben.

    Manche fragen stelle ich dann auch hier.

    Jetzt zu dem Problem:

    Ich lese in einem thread Daten von einem Socket InputStream:

    byte[] b = new byte[1000];
    if (0 < (len = in.read(b)))
    {
      PutData(b) // oder hier halt die kopie die nur len Bytes enthält
    }
    

    Ich dachte wenn man als übergabeparameter schon eine arrayklasse übergeben kann, sollte es doch hinzubekommen sein das die array die korrekte Länge hat.

    MfG



  • Destiniy schrieb:

    Ich dachte wenn man als übergabeparameter schon eine arrayklasse übergeben kann, sollte es doch hinzubekommen sein das die array die korrekte Länge hat.

    Da solltest du dich mal fragen, wie wichtig denn das ist. Du denkst hier viel zu kompliziert und befindest dich auf einer Optimierungsschiene, die typisch für viele C-Anfänger ist.

    Mit dem Übergabeparameter sagst du der read-Methode nur, wieviel Bytes du max. pro Lesevorgang haben möchtest. Hier solltest du eine vernünftige Größe bezogen auf deinen Algorithmus wählen.
    Ich denke, du machst dir sorgen um den Speicherverbrauch. Aber das ist zu 100% egal. Da im Hintergrund der Grabagecollector das ganze verwaltet. Dieser ist nicht auf den optimalen Verbrauch ausgelegt, sondern auf eine gute Geschwindigkeit beim anfordern von Arbeitsspeicher.
    (Hier haben viele C und C++ Programme ihre Schwierigkeiten, sprich sie werden mit der Ausführungszeit langsamer)

    So, mach dir doch mal dein Modell der Speicherbenutzung auf einen Blatt Papier klar.

    1. Male jetzt mal den Arbeitsspeicher in Form eines Balken mit vielen kleinen Kästchen auf.
    2. Jetzt erstellst du ein Array mit 10 Elementen --> 10 Kästchen werden von die belegt
    3. Die read-Methode liest 8 Elemente in dein Array und gibt die restlichen 2 Elemente des Speichers wieder frei --> 8 Kästchen belegt und zwei wieder freigegeben
    4. Die read-Methode liest nun 6 Elemente in das Array und gibt wieder die restlichen 2 (8 - 6 = 2) frei --> 6 Kästchen belegt
    5. Ein anderer Prozess erstellt ein Objekt und belegt die nachfolgenden 13 Kästchen
    6. Die read-Methode liest nun 10 Elemente in das Array, ähm STOP, Boom.
      Wir haben jetzt aus dem Schritt 5 nur 6 Kästchen zur verfügung und die nachfolgenden Bytes im Speicher sind durch Schritt 5 belegt --> Die read-Methode kann das Array nicht vergrößern

    "Die Elemente eines Array sind im Speicher ohne unterbrechung hinterlegt"
    Daher kann man z.B. in C mit den sogenannten Offset's arbeiten

    Die read-Methode müsste jetzt nach einen freien Platz im Arbeitsspeicher suchen, die 6 Elemente dort hin kopieren und den alten Speicher freigeben. Diese Operationen benötigen sehr viel Rechenzeit. Daher ist es sinvoller ein Array mit einer Größe g zu erzeugen und Schritt für Schritt die Daten hineinschreiben, ohne die Ursprungsgröße zu verändern.
    Alleine g sollte man sinnvoll wählen. Nicht zu groß und nicht zu klein 😃

    byte[] b = new byte[1000];
    if (0 < (len = in.read(b)))
    {
      PutData(b) // oder hier halt die kopie die nur len Bytes enthält
    }
    

    Ähm, die Daten kommen schon in regelmäßigen Abständen oder? Wieso "if"?
    Was genau möchtest du machen? Evtl. ist die Methode "available" von BufferedInputStream das was du suchst.
    Möchtest du alles auf einmal lesen und danach den Stream schließen?

    BufferedInputStream inbuf = new BufferedInputStream(socketin);
    int len = inbuf.available();
    byte[] b = new byte[len];
    if (0 < (len = in.read(b)))
    {
      // was auch immer, beachte dass sich len zwischen den Aufrufen ändern kann
      // z.B. bei Multithreading
      // Das macht man relativ selten, daher die Frage "Was genau möchtest du machen"
    }[
    

    Gruß,
    Thomas



  • das ist eine interresant Lösung ich würde das dann so umbauen:

    public void run()
    	{
    		int len;
    		byte[] buffer;
    
    		try
    		{
    			while (!stoprequest)
    			{
    				try
    				{
    					if (0 < (len = in.available()))
    					{
    						buffer = new byte[len];
    						if (0 < (in.read(buffer)) && (null != cbReceiveData)) cbReceiveData.ReceiveData(buffer);
    					}
    				}
    				catch (InterruptedIOException e)
    				{
    					// do again
    				}
    			}
    		}
    		catch (IOException e)
    		{
    
    		}		
    	}
    

    Ich möchte daten von einem Socket Lesen und falls welche vorhanden sind diese weitergeben. Das ist die Funktion die als Thread läuft.

    Das ist jetzt genau das wie ich es haben wollte danke


Anmelden zum Antworten