簡體   English   中英

Java將布爾數組存儲在文件中並快速讀取

[英]Java store boolean array in file and read fast

我需要在文件中存儲包含 80,000 個項目的布爾數組。 我不在乎節省多少時間,我只對數組的加載時間感興趣。 我沒有嘗試通過 DataOutputStream 存儲它,因為它需要訪問每個值。

我試圖通過 3 種方法來做到這一點,例如:

  1. 序列化布爾數組
  2. 使用 BitSet 而不是布爾數組序列化它
  3. 將布爾數組轉換為字節數組,其中 1 為真,0 為假,並通過 FileChannel 使用 ByteBuffer 寫入

為了測試通過這些方法讀取文件,我在循環中運行了每種方法 1,000 次。 所以我得到了如下所示的結果:

  1. 布爾數組的反序列化需要 574 毫秒
  2. BitSet 的反序列化 - 379 毫秒
  3. 通過 MappedByteBuffer 從 FileChannel 獲取字節數組 - 170 毫秒

第一種方法和第二種方法太長了,第三種方法可能根本就不是方法。

也許有最好的方法來完成它,所以我需要你的建議

編輯

每個方法運行一次

  1. 13.8
  2. 8.71
  3. 6.46 毫秒

為每個布爾值編寫一個字節並開發自定義解析器怎么樣? 這可能是最快的方法之一。 如果您想節省空間,您也可以將 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 測試

所以我有一個非常相似的用例,我想序列化/反序列化一個非常大的布爾數組。

我實現了這樣的東西,首先我將布爾數組轉換為整數數組只是為了將多個布爾值分組(這使存儲更高效並且沒有位填充問題)
這現在意味着我們必須構建將給出真/假的包裝方法

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

現在要序列化和反序列化,您可以直接將其轉換為字節流並寫入文件。

我的源代碼,供參考

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM