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

news2024/9/25 19:25:39

背景:

今天在查找一个序列化和反序列化相关的问题时,意外发现使用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();
        }
    }

    @Benchmark
    public 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();
    }

    @Benchmark
    public 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();
    }

    @Benchmark
    public 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();
    }

    @Benchmark
    public 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();
    }

    @Benchmark
    public 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();
    }

    @Benchmark
    public 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;
        }

        @Override
        public void readFully(byte[] bytes) {}

        @Override
        public void readFully(byte[] bytes, int i, int i1) {}

        @Override
        public int skipBytes(int i) {
            data.position(data.position() + i);
            return data.position();
        }

        @Override
        public boolean readBoolean() {
            return data.get() != 0;
        }

        @Override
        public byte readByte() {
            return data.get();
        }

        @Override
        public int readUnsignedByte() {
            return data.get() & 0xFF;
        }

        @Override
        public short readShort() {
            return data.getShort();
        }

        @Override
        public int readUnsignedShort() {
            return data.getShort() & 0xffff;
        }

        @Override
        public char readChar() {
            return data.getChar();
        }

        @Override
        public int readInt() {
            return data.getInt();
        }

        @Override
        public long readLong() {
            return data.getLong();
        }

        @Override
        public float readFloat() {
            return data.getFloat();
        }

        @Override
        public double readDouble() {
            return data.getDouble();
        }

        @Override
        public String readLine() {
            return null;
        }

        @Override
        public String readUTF() {
            return null;
        }
    }


}

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1013931.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

#循循渐进学5单片机#中断与数码管动态显示#not.5

1、掌握C语言数组的概念、定义和应用。 1&#xff09;数组是一组变量&#xff0c;这组变量需要满足三个条件&#xff1a; 具有相同的数组类型 具有相同的名字 在存储器中是连续的 2&#xff09;声明和初始化 数组类型 数组名【数组长度】 数组类型 数组名【数组长度】 …

批量多字段唯一性校验

批量多字段唯一性校验 思路&#xff1a; 查询列表本身是否含有重复数据新增修改分开考虑&#xff0c;新增只考虑数据库中是否有相同数据&#xff0c;修改不仅要考虑数据库中是否有相同数据&#xff0c;还要排除自身。由于是批量校验&#xff0c;排除自身只需考虑所有修改操作…

LeetCode【3. 无重复字符的最长子串】

工欲善其事必先利其器 题目&#xff1a;给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 public int lengthOfLongestSubstring(String s) {int n s.length();int[] charIndex new int[128]; // 用于存储字符的索引&#xff0c;ASCII字符集共有…

docker 操作redis

1查看容器 2进入容器 exec表示在运行的容器中执行命令it表示以终端交互的方式执行命令/bin/bash表示需要指定的命令 3进入容器后可通过redis-cli命令连接容器内的redis服务器&#xff0c;可通过set创建变量&#xff0c;get获取变量的值 4key * 查看所有key 通过ping 查看redi…

使用node实现websocket

使用node实现websocket 什么是websocket websocket代表了Web应用程序通信方式的根本转变。不同于传统的HTTP请求响应周期&#xff0c;即客户端从服务器请求数据并等待响应&#xff0c;websocket在客户端和服务器之间建立一个持久的全双工连接。这意味着一旦建立了websocket&a…

电力系统IEEE14节点系统同步模型(Simulink)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

深度解析shell脚本的命令的原理之mv

mv 是 Unix 或 Linux 中的一个基本命令&#xff0c;用于移动或重命名文件和目录。以下是对这个命令的深度解析&#xff1a; 基本操作&#xff1a;mv 命令的基本操作是将一个或多个源文件或目录移动到一个目标文件或目录&#xff0c;或者重命名源文件或目录。这是通过改变文件系…

【算法训练-队列 一】【结构特性】用两个栈实现队列

废话不多说&#xff0c;喊一句号子鼓励自己&#xff1a;程序员永不失业&#xff0c;程序员走向架构&#xff01;本篇Blog的主题是【队列的结构特性】&#xff0c;使用【队列】这个基本的数据结构来实现&#xff0c;这个高频题的站点是&#xff1a;CodeTop&#xff0c;筛选条件为…

腾讯mini项目-【指标监控服务重构】2023-08-04

今日已办 关于 span-references 的调研 https://github.com/DataDog/dd-trace-js/issues/1761 https://github.com/open-telemetry/opentelemetry-specification/blob/874a451e7f6ac7fc54423ee3f03e5394197be35b/specification/compatibility/opentracing.md#span-references h…

前端面试的话术集锦第 17 篇博文——高频考点(TCP知识点)

这是记录前端面试的话术集锦第十七篇博文——高频考点(TCP知识点),我会不断更新该博文。❗❗❗ 首先还是先来解答这个常考面试题关于TCP部分的内容,然后再详细去学习这个协议。 1. UDP 与 TCP 的区别是什么? TCP基本是和UDP反着来,建立连接断开连接都需要先需要进行握手…

VR虚拟仿真在旅游课堂教学演示

首先&#xff0c;VR虚拟仿真能够为学生提供逼真的旅游体验。传统的旅游课堂教学主要以图片、文字和视频为主要教学工具&#xff0c;这无法给学生带来身临其境的感觉。而VR技术能够通过360度全景视角、立体声音和触觉反馈等功能&#xff0c;将学生置身于虚拟的旅游场景中。无论是…

软件测试/测试开发丨Web自动化—capability参数配置 学习笔记

点此获取更多相关资料 本文为霍格沃兹测试开发学社学员学习笔记分享 原文链接&#xff1a;https://ceshiren.com/t/topic/27336 一、capability概述 capability是webdriver支持的标准命令之外的扩展命令&#xff08;配置信息&#xff09;配置web驱动属性&#xff0c;如浏览器名…

基于element-ui的年份范围选择器

基于element-ui的年份范围选择器 element-ui官方只有日期范围和月份范围选择器&#xff0c;根据需求场景需要&#xff0c;支持年份选择器&#xff0c;原本使用两个分开的年份选择器实现的&#xff0c;但是往往有些是不能接受的。在网上找了很多都没有合适的&#xff0c;所以打…

数据结构与算法--排序算法复习

目录 1.三种常见的简单排序&#xff1a; 1.1冒泡排序 1.2 选择排序 1.3 插⼊排序 2 常见高级排序算法 2.1 希尔排序 2.2 快速排序 2.3 归并排序 2.4计数排序 先上结论&#xff1a; 1.三种常见的简单排序&#xff1a; 1.1冒泡排序 1.⾸先在未排序数组的⾸位开始&#…

Spring boot 实践(16)Nacos server 2.2.3 下载安装

1、Nacos server下载 登录网址Releases alibaba/nacos GitHub&#xff0c;进入下载页面&#xff0c;显示如下&#xff1a; 选择“nacos-server-2.2.3.zip”版本 解压缩&#xff0c;目录文件如下图所示&#xff1a; 配置文件位于“conf”目录下&#xff0c;名称为“applicat…

写作萝卜:基于人工智能的AI智能写作工具平台

【产品介绍】​ 名称​ 写作萝卜​ 具体描述​ 写作萝卜是一款一站式AI智能写作平台&#xff0c;它可以帮助用户快速完成各种类型的写作任务&#xff0c;如文章 改写、降重、生成、校对、转换等。​ 写作萝卜的核心功能是AI智能改…

arcgis js 缓冲区分析(GP服务)

arcgis文档中的有提供缓冲区的接口 geometryService&#xff0c;但要4.19后版本才提供 案例中使用的版本为4.16&#xff0c;因此这里的缓冲区分析借助gp工具 新建服务 1、打开arcmap 选择工具将要存放的文件夹&#xff0c;右键> new > Toolbox 对新建好的工具的mode…

网站排名下降的原因和解决方法(SEO优化失误可能导致网站排名下降)

SEO优化是网站推广的重要环节&#xff0c;它可以提升网站的访问量和排名。但是&#xff0c;SEO优化不当也可能会导致网站排名下降。本文将分析SEO优化失误可能导致网站排名下降的原因&#xff0c;并提供相应的解决方法。 一&#xff1a;标题——SEO优化过度 SEO优化的目的是为…

解决sass问题:npm ERR! node-sass@9.0.0 postinstall: `node scripts/build.js`

目录 一、遇到问题 解决办法 二、 再次遇到问题 解决办法 题外话 一、遇到问题 1.运行这个项目的适合&#xff0c;遇到了没有sass的问题 解决办法 然后就用命令下载sass npm install node-sass 二、 再次遇到问题 2.下载sass的时候又发现了一个这样的问题 npm ER…

黑马JVM总结(九)

&#xff08;1&#xff09;StringTable_调优1 我们知道StringTable底层是一个哈希表&#xff0c;哈希表的性能是跟它的大小相关的&#xff0c;如果哈希表这个桶的个数比较多&#xff0c;元素相对分散&#xff0c;哈希碰撞的几率就会减少&#xff0c;查找的速度较快&#xff0c…