繁体   English   中英

首次访问时RandomAccessFile速度很慢

[英]RandomAccessFile is slow on first access

我目前正在使用RandomAccessFile并遇到一种奇怪的现象。 我正在访问一个大小为1.1TB的文件,并且仅包含等于00000000的字节。

我通过以下方式实现RandomAccessFile:

RandomAccessFile raf = new RandomAccessFile(new File("./db.bin"),"rw");

因此,我的程序正在生成代表BIT位置的Long值的大型列表,一旦达到1000个条目,它将把数据刷新到文件中:

    public void flush() {
       for( long l : lLongs ) {
           lseek = Long.divideUnsigned(l, 8L);
           raf.seek( lseek );
           byte b = raf.readByte();
           raf.seek( lseek );
           raf.writeByte( editByte(b,(int)l % 8) );
       }
       raf.close();
    }

    public byte editByte( byte b, int iBit ) {
      if( !isSet(b,iBit) ) {
        b = (byte)(b + Math.pow( 2, iBit));
      }
      return b;
    }

    boolean isSet(byte value, int bit){
       return (value >> bit & 1) == 1;
    }

现在我想知道为什么要花这么长时间? 对于1000个条目,平均需要15秒。 但是,如果我取消程序并重新启动它,则1000次输入只需要5毫秒(长位置保持不变)

这是为什么? 有人可以帮我解决此问题吗?

逻辑上的解释是,第一次启动需要实际读取文件,而另一个启动需要从内存缓存中获取文件,因此速度要快得多。

同样是第二次,如果我没看错的话就不需要写数据了。

如果您想得到更好的东西,可以尝试使用类似的顺序方法:

private static final int CHUNK_SIZE=512*8*1024;  // 4Mb chunk

private RandomAccessFile raf; 
private long currentChunk=-1;
private byte[] chunk=new byte[CHUNK_SIZE];

public void flush() throws Exception{
    raf = new RandomAccessFile(new File("./db.bin"),"rw");
    List<Long> c=something();

    c.stream().sorted().forEach(this::process);

    saveChunk();
}

public void process(long l) {
    try {
        if (l/8/CHUNCK_SIZE!=currentChunk) {
            saveChunk();
            loadNextChunk();
        }

        long posInMem=(l/8) - (CHUNK_SIZE*currentChunk);
        byte b=chunk[(int)posInMem];
        chunk[(int)posInMem]=editByte(b,(int)l % 8);
    }catch(Exception e) {
        e.printStackTrace();
    }
}

private void loadNextChunk()throws Exception {
    currentChunk++;
    raf.seek(currentChunk*CHUNK_SIZE);
    raf.readFully(chunk, 0, CHUNK_SIZE);
}

private void saveChunk() throws Exception {
    if (currentChunk<0)return;
    raf.seek(currentChunk*CHUNK_SIZE);
    raf.write(chunk, 0, CHUNK_SIZE);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM