将字节数组转换为浮点数数组

5

我目前正在将一种用于随机二进制文件访问的Delphi方法转换为Java。 Delphi过程使用:

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

如何将字节数组读入单精度浮点数数组中?在Java中是否有不需要迭代数组的等效方法?

我目前正在使用以下代码:

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

但我担心速度问题。字节序不是问题。

3个回答

8
你是否分析了代码并确实发现其是一个问题?必须有某些东西在循环...你确定这是你的代码的瓶颈吗?
话虽如此,我猜测你应该能够使用FloatBuffer来解决问题。不幸的是Sun的JavaDoc已经关闭了,所以我暂时无法链接或检查文档。
使用FloatBuffer,你可能需要:
- 创建与文件相关联的FileChannel(例如使用FileInputStream.getChannel) - 创建ByteBuffer - 使用ByteBuffer.asFloatBuffer创建包装ByteBuffer的FloatBuffer - 使用FileChannel.read(byteBuffer)从ByteBuffer中读取 - 从FloatBuffer中读取
我对java.nio不是特别熟悉/舒适,所以我希望这一切都是正确的,但这可能会相当麻烦。你当前的循环几乎肯定更简单,因此我强烈建议你先检查一下它的性能!顺便说一句,你可能想将当前的FileInputStream包装在BufferedInputStream中。

1
至少在我尝试的第三次中有效。http://java.sun.com/javase/6/docs/api/java/nio/FloatBuffer.html - Michael Myers
我认为这意味着答案是否定的。我想找的是一种在Java中复制指针操作的方法,用字节填充Simple(float)数组,因为我相信(也许不正确),这可以避免迭代。稍后,我可以使用myArray [n]读取值。 - GrahamA
@GrahamA: 你可以使用FloatBuffer来进行块复制,这将是有效的-但代码会更加复杂。基本上你可以拥有效率或简单性,但不能两者兼备。你已经测试过简单代码的速度了吗? - Jon Skeet
使用System.currentTimeMillis()和一个65Mb的文件进行了性能分析。读取了27446条记录。List<float> 140毫秒 ByteBuffer 0在对列表和字节缓冲区(转换为数组后)进行迭代时,时间为16毫秒。我尝试了几个不同大小的结果文件,得到了一致的答案。 - GrahamA
你确定首先清除文件系统缓存吗?否则第一次读取将会命中磁盘,而第二次则不会。此外,16毫秒对你来说真的是个问题吗?即使ByteBuffer更快,这绝对是你的瓶颈吗? - Jon Skeet

3

在Jon的帮助下,最终代码如下:

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

无论是你自己的循环,还是在缓冲区复制方法/操作内部,总会有一个循环存在。除此之外,加速的唯一方法就是找到支持向量操作的硬件和编译器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接