当前位置: 首页 > news >正文

DataInputStream数据读取 Vs ByteBuffer数据读取的巨大性能差距

背景:

今天在查找一个序列化和反序列化相关的问题时,意外发现使用DataInputStream读取和ByteBuffer读取之间性能相差巨大,本文就来记录下这两者在读取整数类型时的性能差异,以便在平时使用的过程中引起注意

DataInputStream数据读取 Vs ByteBuffer数据读取

我们会分别使用DataInputStream和ByteBuffer读取不同长度的字节数组,分别测试读取Short,Int,Long三类整数,然后分别看一下他们的性能

性能测试代码如下:

package org.example.jmh.deserialize;import static java.util.concurrent.TimeUnit.MICROSECONDS;
import static org.example.jmh.deserialize.DataUtil.createByteArray;import java.io.ByteArrayInputStream;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;@Warmup(iterations = 2, time = 2)
@Measurement(iterations = 3, time = 10)
@Fork(1)
@OutputTimeUnit(MICROSECONDS)
public class ByteBufferVsByteArrayDataInputBenchmark {@State(Scope.Benchmark)public static class ByteBufferBackedDataInputState {ByteBuffer buffer;DataInput dataInput;@Param({"8", "32", "64", "128"})int size;byte[] data;public void createData() {this.data = createByteArray(size);}@Setup(Level.Trial)public void init() {createData();this.buffer = ByteBuffer.wrap(data);this.dataInput = new BufferDataInput(buffer);}void reset() {buffer.position(0);}}@State(Scope.Benchmark)public static class StreamBackedDataInpuState {ByteArrayInputStream bis;DataInput dataInput;@Param({"8", "32", "64", "128"})int size;byte[] data;public void createData() {this.data = createByteArray(size);}@Setup(Level.Trial)public void init() {createData();this.bis = new ByteArrayInputStream(data);this.dataInput = new DataInputStream(bis);}void reset() {bis.reset();}}@Benchmarkpublic void streamBackedDataInputReadShort(StreamBackedDataInpuState state, Blackhole bh) throws IOException {DataInput input = state.dataInput;int size = state.size;int pos = 0;while (pos < size) {bh.consume(input.readShort());pos += 2;}state.reset();}@Benchmarkpublic void bufferBackedDataInputReadShort(ByteBufferBackedDataInputState state, Blackhole bh) throws IOException {DataInput input = state.dataInput;int size = state.size;int pos = 0;while (pos < size) {bh.consume(input.readShort());pos += 2;}state.reset();}@Benchmarkpublic void streamBackedDataInputReadInt(StreamBackedDataInpuState state, Blackhole bh) throws IOException {DataInput input = state.dataInput;int size = state.size;int pos = 0;while (pos < size) {bh.consume(input.readInt());pos += 4;}state.reset();}@Benchmarkpublic void bufferBackedDataInputReadInt(ByteBufferBackedDataInputState state, Blackhole bh) throws IOException {DataInput input = state.dataInput;int size = state.size;int pos = 0;while (pos < size) {bh.consume(input.readInt());pos += 4;}state.reset();}@Benchmarkpublic void streamBackedDataInputReadLong(StreamBackedDataInpuState state, Blackhole bh) throws IOException {DataInput input = state.dataInput;int size = state.size;int pos = 0;while (pos < size) {bh.consume(input.readLong());pos += 8;}state.reset();}@Benchmarkpublic void bufferBackedDataInputReadLong(ByteBufferBackedDataInputState state, Blackhole bh) throws IOException {DataInput input = state.dataInput;int size = state.size;int pos = 0;while (pos < size) {bh.consume(input.readLong());pos += 8;}state.reset();}public static class BufferDataInput implements DataInput {private final ByteBuffer data;public BufferDataInput(ByteBuffer data) {this.data = data;}@Overridepublic void readFully(byte[] bytes) {}@Overridepublic void readFully(byte[] bytes, int i, int i1) {}@Overridepublic int skipBytes(int i) {data.position(data.position() + i);return data.position();}@Overridepublic boolean readBoolean() {return data.get() != 0;}@Overridepublic byte readByte() {return data.get();}@Overridepublic int readUnsignedByte() {return data.get() & 0xFF;}@Overridepublic short readShort() {return data.getShort();}@Overridepublic int readUnsignedShort() {return data.getShort() & 0xffff;}@Overridepublic char readChar() {return data.getChar();}@Overridepublic int readInt() {return data.getInt();}@Overridepublic long readLong() {return data.getLong();}@Overridepublic float readFloat() {return data.getFloat();}@Overridepublic double readDouble() {return data.getDouble();}@Overridepublic String readLine() {return null;}@Overridepublic String readUTF() {return null;}}}

jmh的测试结果:
在这里插入图片描述
从结果可以看出,不论是读取Short,Int还是Long,ByteBuffer都比DataInputStream有很大的性能优势,大概3-4倍的差异,那么你知道造成这种性能差距的原因是什么吗,留个悬念

http://www.lryc.cn/news/167468.html

相关文章:

  • org.apache.flink.table.api.TableException: Sink does not exists
  • 【多线程】CAS 详解
  • 卷积神经网络实现咖啡豆分类 - P7
  • C++之默认与自定义构造函数问题(二百一十七)
  • Docker从认识到实践再到底层原理(五)|Docker镜像
  • 【Flowable】任务监听器(五)
  • spring-kafka中ContainerProperties.AckMode详解
  • 【rpc】Dubbo和Zookeeper结合使用,它们的作用与联系(通俗易懂,一文理解)
  • ChatGPT的未来
  • Pytorch模型转ONNX部署
  • k8s优雅停服
  • 面试题五:computed的使用
  • 完美的分布式监控系统 Prometheus与优雅的开源可视化平台 Grafana
  • 黑马JVM总结(九)
  • 如何使用 RunwayML 进行创意 AI 创作
  • 【css】能被4整除 css :class,判断一个数能否被另外一个数整除,余数
  • ChatGPT与日本首相交流核废水事件-精准Prompt...
  • 关于 firefox 不能访问 http 的解决
  • 68、Spring Data JPA 的 方法名关键字查询
  • Brother CNC联网数采集和远程控制
  • Jenkins 编译 Maven 项目提示错误 version 17
  • 数据结构——排序算法——堆排序
  • 【Spring事务底层实现原理】
  • docker快速安装redis,mysql,minio,nacos等常用软件【持续更新】
  • SCRUM产品负责人(CSPO)认证培训课程
  • python连接mysql数据库的练习
  • 扩散模型在图像生成中的应用:从真实样例到逼真图像的奇妙转变
  • Windows 打包 Docker 提示环境错误: no DOCKER_HOST environment variable
  • 2023.9.8 基于传输层协议 UDP 和 TCP 编写网络通信程序
  • 单例模式,适用于对象唯一的情景(设计模式与开发实践 P4)