随机IO小测试

1.测试方式

分别采用随机读取和顺序读取的方式读取文件

2.Demo代码

package test;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class IOTest {

    public static void main(String[] args) throws IOException {
        //缓存大小设置为1000000字节
        int bufferSize=100000000;
        //要读取的文件路径
        String filePath = "D:\\testc.rar";

        //顺序读取计算所用时间
        sequentialRead(filePath,bufferSize);
        //随机读取,计算所用时间
        randomRead(filePath,bufferSize);


    }



    private static void randomRead(String filePath, int bufferSize) throws IOException {
        //创建文件进行随机读取
        RandomAccessFile aFile = new RandomAccessFile(filePath,"r");
        FileChannel inChannel = aFile.getChannel();

        //开始时间
        Long beginTime = System.currentTimeMillis();

        //创建buffer
        ByteBuffer buffer = ByteBuffer.allocate(bufferSize);

        //进行10次随机读取
        for (int i = 0; i < 10; i++) {
            long pos =(long) (Math.random()*inChannel.size());
            //根据随机位置读取文件
            inChannel.read(buffer,pos);
            buffer.clear();
        }

        //关闭文件和通道
        inChannel.close();
        aFile.close();

        //结束时间,记录耗时
        Long endTime = System.currentTimeMillis();
        long time  = endTime-beginTime;
        System.out.println("随机读耗时:"+time+"ms");
    }

    private static void sequentialRead(String filePath, int bufferSize) throws IOException {
        //顺序读取
        File aFile = new File(filePath);
        FileInputStream inFile = new FileInputStream(aFile);
        FileChannel inChannel = inFile.getChannel();

        ByteBuffer buffer = ByteBuffer.allocate(bufferSize);
        //开始时间
        Long beginTime = System.currentTimeMillis();

        //顺序读取十次
        for (int i = 0; i < 10; i++) {
            inChannel.read(buffer);
            buffer.clear();
        }

        //关闭文件和通道

        inChannel.close();
        inFile.close();

        //记录耗时
        Long endTime = System.currentTimeMillis();
        long time = endTime-beginTime;
        System.out.println("顺序读取耗时:"+time +"ms");



    }
}

3.测试结果

bufferSize(byte)文件大小顺序读耗时(ms)随机读耗时(ms)随机/顺序
100000000320M3526091.73 
2306662.90 
2756502.36 
1.2G6487891.22 
6588241.25 
6346971.10 
10000006.4M561.20 
451.25 
540.80 
320M4102.50 
5122.40 
6111.83 
1.2G14171.21 
6142.33 
6152.50 
1006.4M210.50 
111.00 
111.00 
320M221.00 
122.00 
430.75 
1.2G144.00 
122.00 
122.00 

4.结果分析

影响测试结果的因素很多,测试注意点如下

1.文件不能太小,文件太小可能会第一次读取的时候就被加到了缓存中,后续都是读取的缓存。
2.读取顺序不能变。如果先随机读,在顺序读。随机读的时候会把一些数据放入缓存,顺序读的时候就会加速。这样就无法分辨是因为顺序读快还是因为读缓存导致的快。
3.bufferSize不能太小,原因如1。

除了文件太小的情况下会个别案例出现随机读更快的情况,绝大多数都是顺序读更快。

相关问题

顺序读取具体能快多少?

这个问题没有一个固定的答案,因为顺序读取与随机读取的速度差异会受到很多因素的影响,包括硬盘的类型、硬盘的转速、数据的大小、存储设备的缓冲区大小、操作系统的文件系统类型、数据的碎片化程度等等。

在传统的机械硬盘(HDD)中,顺序读取的速度可以比随机读取快十倍甚至更多。对于固态硬盘(SSD)来说,由于它们的硬盘头移动速度极快,因此顺序读取和随机读取的速度差距会小很多,但通常顺序读取的速度依然会比随机读取快。

值得注意的是,这里说的是一般情况,具体的速度差异还需要实际测试才能得出。

5.java技术栈中的使用

1.kafka.是按顺序写入的

2.mysql InnoDB:在批量写入的时候会使用顺序IO做优化

3.starRocks:先将数据写入内存缓冲区,再以顺序IO方式刷入磁盘。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值