2009-02-20 7 views
5

Actualmente, estoy convirtiendo un método Delphi utilizado para el acceso aleatorio de archivos binarios a Java. El procedimiento Delphi usa:Conversión de una matriz de bytes en una matriz de flotantes

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

Para leer una matriz de bytes en una matriz de Single. ¿Hay una forma equivalente de hacer esto en Java sin iterar a través de la matriz?

actualmente estoy usando

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

Pero estoy preocupado por la velocidad. Endianness no es un problema.

Respuesta

8

¿Ha perfilado el código y realmente lo encontró como un problema? Algo va a tener que repetir ... ¿de verdad está seguro de que esto es un cuello de botella en su código?

Habiendo dicho todo eso, debería poder usar un FloatBuffer que sospecho que hace lo que quiere. Desafortunadamente, el JavaDoc de Sun no funciona, por lo que no puedo vincularlo o consultar la documentación en el momento.

Para utilizar un FloatBuffer, lo que probablemente quiere:

  • Crear una FileChannel asociado con el archivo (por ejemplo, con FileInputStream.getChannel)
  • Crear un ByteBuffer
  • Crear una FloatBuffer envolviendo el ByteBuffer, con ByteBuffer.asFloatBuffer
  • Leer en el ByteBuffer con FileChannel.read (ByteBuffer)
  • leer desde el FloatBuffer

no estoy particularmente familiarizado/cómodo con java.nio, así que esperanza todo esto es correcto - pero es probable que sea bastante incómoda. Su ciclo actual es casi seguro más simple, por lo que le sugiero que compruebe el rendimiento de ese primero. Es posible que desee envolver su FileInputStream actual en un BufferedInputStream, por cierto.

+1

Funciona para mí, al menos la tercera vez que lo intenté. http://java.sun.com/javase/6/docs/api/java/nio/FloatBuffer.html –

+0

Todavía estoy deprimido. Creo que debe ser una división neta ... –

+0

Creo que eso significa que la respuesta es no. Lo que estaba buscando era una forma de replicar la operación del puntero en Java, llenando una matriz de Simple (float) con bytes, como creo (quizás incorrectamente) que esto evita la iteración. Más tarde puedo leer valores usando myArray [n] – GrahamA

3

Sobre la base de la ayuda proporcionada por Jon el código final se parece a esto:

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); 
} 
0

Siempre habrá un bucle en algún lugar - si se trata de su propio, o internamente dentro de un método de copia de tampón/operación. La única forma de acelerar las cosas más allá es encontrar hardware y un compilador que admita operaciones vectoriales.

Cuestiones relacionadas