Frage Konvertieren eines Array von Bytes in ein Array von Floats


Ich konvertiere gerade eine Delphi-Methode, die für den wahlfreien Zugriff auf binäre Dateien verwendet wird, in Java. Das Delphi-Verfahren verwendet:

TSingleArray  = Array[0..MAXSIZE] of Single
...
procedure GetLinkValues(const LinkVar: Integer;  const TimePeriod: Integer; var Value: PSingleArray);
...
BlockRead(Fout, Value^, Nlinks*SizeOf(Single));

Um ein Array von Bytes in ein Array von Single zu lesen. Gibt es eine entsprechende Vorgehensweise in Java, ohne das Array zu durchlaufen?

Ich benutze derzeit

List<Float> l = new ArrayList<Float>();
…
for (int i = 0 ; i < nLinks ; i++ )
l.add( resultsFile.readFloat());

Aber ich bin besorgt über die Geschwindigkeit. Endianess ist kein Problem.


5
2018-02-20 16:52


Ursprung


Antworten:


Haben Sie den Code profiliert und festgestellt, dass er ein Problem darstellt? etwas wird eine Schleife machen müssen ... Sind Sie wirklich sicher, dass dies ein Engpass in Ihrem Code ist?

Nachdem Sie all das gesagt haben, sollten Sie in der Lage sein, einen FloatBuffer zu benutzen, von dem ich annehme, dass er tut, was Sie wollen. Leider ist Suns JavaDoc nicht verfügbar, daher kann ich nicht so schnell auf die Dokumentation verlinken oder sie überprüfen.

Um einen FloatBuffer zu verwenden, möchtest du wahrscheinlich:

  • Erstellen Sie einen FileChannel, der der Datei zugeordnet ist (z. B. mit FileInputStream.getChannel)
  • Erstellen Sie einen ByteBuffer
  • Erstellen Sie einen FloatBuffer, der den ByteBuffer mit ByteBuffer.asFloatBuffer umhüllt
  • Einlesen in den ByteBuffer mit FileChannel.read (byteBuffer)
  • Lesen Sie aus dem FloatBuffer

Ich bin nicht besonders vertraut mit java.nio, also ich Hoffnung Das ist alles in Ordnung - aber es ist wahrscheinlich ziemlich fummelig. Ihre aktuelle Schleife ist mit ziemlicher Sicherheit einfacher, daher empfehle ich Ihnen dringend, zuerst die Leistung zu überprüfen! Vielleicht möchten Sie Ihren aktuellen FileInputStream in einem BufferedInputStream, btw.


9
2018-02-20 16:57



Basierend auf der Hilfe von Jon sieht der finale Code so aus:

byte[] bt = new byte[nLinks * 4];
List<Float> l = new ArrayList<Float>();
if (linkVar != 0 && timePeriod < nPeriods) {
    long p1 = RECORDSIZE * (nNodes * NODEVARS + nLinks * LINKVARS);
    long p2 = RECORDSIZE * (nNodes * NODEVARS + nLinks * (linkVar - 1));
    long p3 = offset2 + (timePeriod * p1) + p2;
    resultsFile.seek(p3);

    resultsFile.read(bt, 0, nLinks * 4);
    ByteBuffer bb = ByteBuffer.wrap(bt);
    bb.rewind();
    bb.asFloatBuffer().get(values);
}

3
2018-02-23 11:42



Es wird immer irgendwo eine Schleife geben - sei es Ihre eigene oder intern in einer Pufferkopie-Methode / Operation. Die einzige Möglichkeit, Dinge darüber hinaus zu beschleunigen, ist die Suche nach Hardware und einem Compiler, der Vektoroperationen unterstützt.


0
2018-01-11 16:29