【问题标题】:Fastest way to read long[] from file?从文件中读取 long[] 的最快方法?
【发布时间】:2011-04-18 22:30:24
【问题描述】:

我有一个包含大约 200,000 个长值的文件,我想尽快将其读入 long[]。它适用于 Android 应用程序;函数调用很慢(所以任何涉及使用“for”循环一次读取很长时间的东西都会非常慢),我需要快速加载。我可以使用什么?我看到的所有东西似乎都只能快速读取字节。

我之前使用过 NIO 包中的 ByteBuffer 和 FileChannel,这似乎是从文件中加载值数组的一种非常快速的方法。但是,我无法弄清楚如何使用它来将数据读入 long[]。我尝试将 long[] 包装为 LongBuffer,但我看不到任何可以将文件中的数据输入 LongBuffer 的方法。

编辑:无论我使用什么方法,我都需要能够在最后的long[] 数组上使用Arrays.binarySearch。

【问题讨论】:

  • 我不确定这些有什么帮助。我看不出他们是如何回答我的问题的。

标签: java android file optimization io


【解决方案1】:

没有办法将byte[]转换成long[]。但是,您可以尝试使用FileChannel 将内容读入ByteBuffer,然后获取LongBuffer 到ByteBuffer.asLongBuffer,您可以从中获取long[] 到LongBuffer.array()。

您也可以尝试FileChannel.map 来获取文件的MappedByteBuffer。这可能比通过FileChannel.read 更快。

如果这不起作用,您可以尝试使用FileChannel 将内容读入ByteBuffer,然后使用ByteBuffer.getLong(index) 访问其中的longs。


另一种解决方案。 (循环中没有方法调用:-)

byte[] byteArray = new byte[longCount * 8];
FileInputStream fis = new FileInputStream("lotsoflongs");
fis.read(byteArray);
fis.close();
for (int i = 0; i < longCount; i += 8)
    longArray[i >> 3] = ((long) byteArray[0+i]        << 56) +
                        ((long)(byteArray[1+i] & 255) << 48) +
                        ((long)(byteArray[2+i] & 255) << 40) +
                        ((long)(byteArray[3+i] & 255) << 32) +
                        ((long)(byteArray[4+i] & 255) << 24) +
                              ((byteArray[5+i] & 255) << 16) +
                              ((byteArray[6+i] & 255) <<  8) +
                              ((byteArray[7+i] & 255) <<  0);

我现在对一些解决方案进行了基准测试,这似乎是最快的方法。另外,请注意fis.read(byteArray) 中读取的实际字节数可能小于 byteArray 的实际大小。因此,如果这应该正确完成,您需要将其放入一个循环中,直到所有字节都被读取为止。

【讨论】:

  • 我需要能够像 long[] 之后使用 long[]将它与 Arrays.binarySearch 一起使用
  • 如何实现一个 List 的 longs,由一个字节数组支持,并使用 Collections.binarySearch?
  • 我不确定你的意思是什么?我将如何创建这样的 List 对象?
  • 像这样:class MyList implements java.util.List { byte[] backingArray; MyList(byte[] data) { backingArray = data; } /* all list methods you need */ }
  • 这比使用DataInputStream的getLong()方法快吗?介意用您测试的不同方法发布您的结果吗? ^^
【解决方案2】:

尝试使用DataInputStream。由于您可以轻松找出文件的长度,因此您也知道它包含多少个元素(文件大小 / 8 字节)。

 DataInputStream dataStream = new DataInputStream(inputStream);

 long count = filesize/8;
 long[] longArray = new long[count];

 for(int i=0;i<count;i++) 
     longArray[i] = dataStream.getLong();

猜猜这应该足以给你一个想法。

【讨论】:

  • @aioobe:为什么不为 LongBuffer 实现自己的 binarySearch 版本?应该相当容易,然后你就完成了。 :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-26
  • 1970-01-01
  • 2019-07-31
相关资源
最近更新 更多