原创 简单测试分析:流式IO,NIO,内存映射读取速度

2019-11-26 10:28 1993 15 2 分类: 测试测量

测试环境

cpu: intel® core™ i7-8750H

内存:16G

硬盘:512 SSD

测试文件:四个文件的zip包,压缩后大小 1.73 GB

测试结果

流式IO读取样例代码

final int BUFFER_SIZE = 1024;

int i = 0;

byte[] bytes = new byte[BUFFER_SIZE];

File file2 = new File(filePath);

FileInputStream in2 = new FileInputStream(file2);

long begin3 = System.currentTimeMillis();

while (in2.read(bytes) > 0){

i++;

}

in2.close();

long end3 = System.currentTimeMillis();

System.out.println("count is:" + i);

System.out.println("time is:" + (end3 - begin3));

NIO读取样例代码

final int BUFFER_SIZE = 1024;

int i = 0;

File file = new File(filePath);

FileInputStream in = new FileInputStream(file);

FileChannel channel2 = in.getChannel();

ByteBuffer buff = ByteBuffer.allocate(BUFFER_SIZE);

long begin2 = System.currentTimeMillis();

while (channel2.read(buff) != -1) {

i++;

buff.flip();

buff.clear();

}

channel2.close();

long end2 = System.currentTimeMillis();

System.out.println("count is:" + i);

System.out.println("time is:" + (end2 - begin2));

内存映射读取样例代码

final int BUFFER_SIZE = 1024;

int i = 0;

byte[] bytes = new byte[BUFFER_SIZE];

RandomAccessFile memoryMappedFile = new RandomAccessFile(filePath, "rw");

FileChannel channel = memoryMappedFile.getChannel();

final long len = channel.size();

long begin = System.currentTimeMillis();

MappedByteBuffer out = channel.map(FileChannel.MapMode.READ_WRITE, 0, len);

for (int offset = 0; offset < len; offset += BUFFER_SIZE) {

i++;

if (len - offset >= BUFFER_SIZE) {

out.get(bytes);

} else {

out.get(bytes,0,(int) len - offset);

}

}

memoryMappedFile.close();

long end = System.currentTimeMillis();

System.out.println("count is:" + i);

System.out.println("time is: " + (end - begin));

测试结果

分别测试缓冲区为 1K,1M,10M.每种情况执行三次

简单测试分析:流式IO,NIO,内存映射读取速度

结论

从表格可以看出总体来说传统流式IO读取速度最慢。

三种方式速度最快的情况都是1M,即缓冲区并非越大越快。

在缓冲区较小的时候流式IO和NIO都慢的无法忍受且读取速度相差不大。

使用内存映射方式无论缓冲区大小读取速度相对稳定。

在参数合适情况下NIO读取速度最快。

疑问

当缓冲区较小时为何NIO读取速度如此慢?

缓冲区大小为何对于内存映射影响较小?

解答

针对疑问一让我想到NIO read方法中的几行代码。打开read 函数源码就能找到。

sun.nio.ch.IOUtil#read(java.io.FileDescriptor, java.nio.ByteBuffer, long, sun.nio.ch.NativeDispatcher)

static int read(FileDescriptor var0, ByteBuffer var1, long var2, NativeDispatcher var4) throws IOException {

if (var1.isReadOnly()) {

throw new IllegalArgumentException("Read-only buffer");

} else if (var1 instanceof DirectBuffer) {

return readIntoNativeBuffer(var0, var1, var2, var4);

} else {

ByteBuffer var5 = Util.getTemporaryDirectBuffer(var1.remaining());

int var7;

try {

int var6 = readIntoNativeBuffer(var0, var5, var2, var4);

var5.flip();

if (var6 > 0) {

var1.put(var5);

}

var7 = var6;

} finally {

Util.offerFirstTemporaryDirectBuffer(var5);

}

return var7;

}

}

从这里可以看出如果缓冲区不是直接内存JDK会创建一个大小相同的临时直接内存读取文件,再从临时的直接内存拷贝。因此修改代码使用直接内存作为缓冲区再次测试

// 使用直接内存作为缓冲区

ByteBuffer buff = ByteBuffer.allocateDirect(BUFFER_SIZE);

简单测试分析:流式IO,NIO,内存映射读取速度

从测试结果看,使用直接内存作为缓冲区对于读取速度有一定提升,但是对于缓冲区很小的时候依然很慢,应该就是本身读取方式的问题了。

针对疑问二由于内存映射虽然不会完全将文件加载到内存,但是有预读在内存间拷贝所以速度很快,有一点不能解释,使用内存映射只是节省了数据从内核区拷贝到用户区和其他读取方式只是多了一次内存拷贝为何会慢如此多--------待探索

文章评论1条评论)

登录后参与讨论

curton 2019-12-2 20:51

学习了
相关推荐阅读
红旗不倒 2023-04-24 16:28
多谐振荡电路原理、计算公式,施密特,单稳态电路,多谐振荡电路优缺点
多谐振荡电路原理、多谐振荡电路计算公式、施密特,单稳态电路,多谐振荡电路优缺点多谐振荡电路是一种具有放大作用的电路,它利用电容的充放电特性来产生振荡信号。多谐振荡器的基本原理是,当外加在电感两端的交流...
红旗不倒 2023-03-29 17:23
可控硅材料介绍、作用、与igbt优缺点对比
本文分享可控硅材料介绍、作用、可控硅和igbt优缺点对比可控硅是什么材料,有哪些作用可控硅,又称为晶闸管(SCR),是一种电子器件,常用于控制交流电的电压和功率。可控硅由四层半导体材料组成,其中P型半...
红旗不倒 2023-03-24 10:49
强大的chatgpt NLP技术,可能无法单独吞噬世界?
人工智能编码 尽管软件被认为是“吞噬世界”,但由于开发人才的获取和构建软件所需任务数量的增加,它在这样做方面受到了严重限制。需要软件开发人员的工作数量正在以远远超过进入市场填补这些职位的熟练专业人员...
红旗不倒 2023-03-20 10:47
ChatGpt汇总:全球各国在6G发展状况?5G、4G、3G、2G和1G的网速和覆盖能力对比
6g 普及了吗,对比5、4、3、2、1G网速、关键核心技术、覆盖能力、成本等汇总对比,全球各国在6G领域的发展状况?网速方面:2G:数字式移动电话技术,可提供更快的数据传输速度和更好的语音质量。4G:...
红旗不倒 2023-03-15 16:49
电机功率计算公式(三相平衡功率、异步电机功率)详细解读,看得明明白白
电机功率的计算公式需要考虑到电机的实际情况、电力质量等因素,因此具体的计算需要根据实际情况进行调整。以下是三相平衡功率和异步电机功率的计算公式:三相平衡功率计算公式:三相电源输入功率 P = √3 ×...
红旗不倒 2022-08-03 18:10
IC面临库存调整、英飞凌Q3收入增长超预期、台积电将用中微刻蚀机生产5纳米
2022年8月3日,半导体行业快讯汇总:15:05据台媒报道,近来半导体行业被“砍单潮”席卷,OSAT(专业委外封测代工)业内人士称,消费电子应用的成熟基础IC面临库存调整,先前数次调涨封测代工费用的...
我要评论
1
15
关闭 站长推荐上一条 /2 下一条