Java 将布尔数组存储在文件中并快速读取
Java store boolean array in file and read fast
我需要在文件中存储包含 80,000 个项目的布尔数组。我不在乎节省多少时间,我只对数组的加载时间感兴趣。
我没有尝试通过 DataOutputStream 存储它,因为它需要访问每个值。
我尝试通过 3 种方法做到这一点,例如:
- 序列化布尔数组
- 使用 BitSet 而不是布尔数组序列化它
- t运行sfer boolean array into byte array,其中1为真,0为假,用ByteBuffer
通过FileChannel写入
为了测试通过这些方法读取文件,我 运行 每个方法循环 1,000 次。所以我得到的结果如下所示:
- 布尔数组的反序列化需要 574 毫秒
- BitSet 反序列化 - 379 毫秒
- 通过 MappedByteBuffer 从 FileChannel 获取字节数组 - 170 毫秒
第一个和第二个方法太长了,第三个可能根本就不是方法。
也许有一个最好的方法来完成它,所以我需要你的建议
编辑
每个方法运行一次
- 13.8
- 8.71
- 6.46
ms 适当地
如何为每个布尔值编写一个字节并开发一个自定义解析器?这可能是最快的方法之一。
如果你想保存 space 你也可以将 8 个布尔值放入一个字节,但这需要一些位移操作。
这是一个简短的示例代码:
public void save() throws IOException
{
boolean[] testData = new boolean[80000];
for(int X=0;X < testData.length; X++)
{
testData[X] = Math.random() > 0.5;
}
FileOutputStream stream = new FileOutputStream(new File("test.bin"));
for (boolean item : testData)
{
stream.write(item ? 1 : 0);
}
stream.close();
}
public boolean[] load() throws IOException
{
long start = System.nanoTime();
File file = new File("test.bin");
FileInputStream inputStream = new FileInputStream(file);
int fileLength = (int) file.length();
byte[] data = new byte[fileLength];
boolean[] output = new boolean[fileLength];
inputStream.read(data);
for (int X = 0; X < data.length; X++)
{
if (data[X] != 0)
{
output[X] = true;
continue;
}
output[X] = false;
}
long end = System.nanoTime() - start;
Console.log("Time: " + end);
return output;
}
加载 80.000 个布尔值大约需要 2 毫秒。
使用 JDK 1.8.0_45
测试
所以我有一个非常相似的用例,我想 serialise/deserialise 一个非常大的布尔数组。
我实现了这样的东西,
首先,我将布尔数组转换为整数数组只是为了合并多个布尔值(这使存储效率更高并且位填充没有问题)
这现在意味着我们必须构建包装器方法,它将提供 true/false
private boolean get (int index) {
int holderIndex = (int) Math.floor(index/buckets);
int internalIndex = index % buckets;
return 0 != (container[holderIndex] & (1 << internalIndex));
}
和
private void set (int index) {
int holderIndex = (int) Math.floor(index/buckets);
int internalIndex = index % buckets;
int value = container[holderIndex];
int newValue = value | (1 << internalIndex);
container[holderIndex] = newValue;
}
现在要进行序列化和反序列化,您可以直接将其转换为字节流并写入文件。
我的源代码,用于 reference
我需要在文件中存储包含 80,000 个项目的布尔数组。我不在乎节省多少时间,我只对数组的加载时间感兴趣。 我没有尝试通过 DataOutputStream 存储它,因为它需要访问每个值。
我尝试通过 3 种方法做到这一点,例如:
- 序列化布尔数组
- 使用 BitSet 而不是布尔数组序列化它
- t运行sfer boolean array into byte array,其中1为真,0为假,用ByteBuffer 通过FileChannel写入
为了测试通过这些方法读取文件,我 运行 每个方法循环 1,000 次。所以我得到的结果如下所示:
- 布尔数组的反序列化需要 574 毫秒
- BitSet 反序列化 - 379 毫秒
- 通过 MappedByteBuffer 从 FileChannel 获取字节数组 - 170 毫秒
第一个和第二个方法太长了,第三个可能根本就不是方法。
也许有一个最好的方法来完成它,所以我需要你的建议
编辑
每个方法运行一次
- 13.8
- 8.71
- 6.46 ms 适当地
如何为每个布尔值编写一个字节并开发一个自定义解析器?这可能是最快的方法之一。 如果你想保存 space 你也可以将 8 个布尔值放入一个字节,但这需要一些位移操作。
这是一个简短的示例代码:
public void save() throws IOException
{
boolean[] testData = new boolean[80000];
for(int X=0;X < testData.length; X++)
{
testData[X] = Math.random() > 0.5;
}
FileOutputStream stream = new FileOutputStream(new File("test.bin"));
for (boolean item : testData)
{
stream.write(item ? 1 : 0);
}
stream.close();
}
public boolean[] load() throws IOException
{
long start = System.nanoTime();
File file = new File("test.bin");
FileInputStream inputStream = new FileInputStream(file);
int fileLength = (int) file.length();
byte[] data = new byte[fileLength];
boolean[] output = new boolean[fileLength];
inputStream.read(data);
for (int X = 0; X < data.length; X++)
{
if (data[X] != 0)
{
output[X] = true;
continue;
}
output[X] = false;
}
long end = System.nanoTime() - start;
Console.log("Time: " + end);
return output;
}
加载 80.000 个布尔值大约需要 2 毫秒。 使用 JDK 1.8.0_45
测试所以我有一个非常相似的用例,我想 serialise/deserialise 一个非常大的布尔数组。
我实现了这样的东西,
首先,我将布尔数组转换为整数数组只是为了合并多个布尔值(这使存储效率更高并且位填充没有问题)
这现在意味着我们必须构建包装器方法,它将提供 true/false
private boolean get (int index) {
int holderIndex = (int) Math.floor(index/buckets);
int internalIndex = index % buckets;
return 0 != (container[holderIndex] & (1 << internalIndex));
}
和
private void set (int index) {
int holderIndex = (int) Math.floor(index/buckets);
int internalIndex = index % buckets;
int value = container[holderIndex];
int newValue = value | (1 << internalIndex);
container[holderIndex] = newValue;
}
现在要进行序列化和反序列化,您可以直接将其转换为字节流并写入文件。
我的源代码,用于 reference