`

将 20M 文件从 30 秒压缩到 1 秒,我是如何做到的?

阅读更多

作者:不学无数的程序员,原文链接:https://urlify.cn/7NRrea

压缩20M文件从30秒到1秒的优化过程

有一个需求需要将前端传过来的10张照片,然后后端进行处理以后压缩成一个压缩包通过网络流传输出去。之前没有接触过用Java压缩文件的,所以就直接上网找了一个例子改了一下用了,改完以后也能使用,但是随着前端所传图片的大小越来越大的时候,耗费的时间也在急剧增加,最后测了一下压缩20M的文件竟然需要30秒的时间。压缩文件的代码如下。

这里找了一张2M大小的图片,并且循环十次进行测试。打印的结果如下,时间大概是30秒。

第一次优化过程-从30秒到2秒

进行优化首先想到的是利用缓冲区 BufferInputStream。在FileInputStream中read() 方法每次只读取一个字节。源码中也有说明。

这是一个调用本地方法与原生操作系统进行交互,从磁盘中读取数据。每读取一个字节的数据就调用一次本地方法与操作系统交互,是非常耗时的。例如我们现在有30000个字节的数据,如果使用FileInputStream那么就需要调用30000次的本地方法来获取这些数据,而如果使用缓冲区的话(这里假设初始的缓冲区大小足够放下30000字节的数据)那么只需要调用一次就行。因为缓冲区在第一次调用read()方法的时候会直接从磁盘中将数据直接读取到内存中。随后再一个字节一个字节的慢慢返回。

BufferedInputStream内部封装了一个byte数组用于存放数据,默认大小是8192

优化过后的代码如下

输出

可以看到相比较于第一次使用FileInputStream效率已经提升了许多了

第二次优化过程-从2秒到1秒

使用缓冲区buffer的话已经是满足了我的需求了,但是秉着学以致用的想法,就想着用NIO中知识进行优化一下。

使用Channel

为什么要用Channel呢?因为在NIO中新出了Channel和ByteBuffer。正是因为它们的结构更加符合操作系统执行I/O的方式,所以其速度相比较于传统IO而言速度有了显著的提高。Channel就像一个包含着煤矿的矿藏,而ByteBuffer则是派送到矿藏的卡车。也就是说我们与数据的交互都是与ByteBuffer的交互。

在NIO中能够产生FileChannel的有三个类。分别是FileInputStream、FileOutputStream、以及既能读又能写的RandomAccessFile。

源码如下

我们可以看到这里并没有使用ByteBuffer进行数据传输,而是使用了transferTo的方法。这个方法是将两个通道进行直连。

这是源码上的描述文字,大概意思就是使用transferTo的效率比循环一个Channel读取出来然后再循环写入另一个Channel好。操作系统能够直接传输字节从文件系统缓存到目标的Channel中,而不需要实际的copy阶段。

copy阶段就是从内核空间转到用户空间的一个过程

可以看到速度相比较使用缓冲区已经有了一些的提高。

内核空间和用户空间

那么为什么从内核空间转向用户空间这段过程会慢呢?首先我们需了解的是什么是内核空间和用户空间。在常用的操作系统中为了保护系统中的核心资源,于是将系统设计为四个区域,越往里权限越大,所以Ring0被称之为内核空间,用来访问一些关键性的资源。Ring3被称之为用户空间。

用户态、内核态:线程处于内核空间称之为内核态,线程处于用户空间属于用户态

那么我们如果此时应用程序(应用程序是都属于用户态的)需要访问核心资源怎么办呢?那就需要调用内核中所暴露出的接口用以调用,称之为系统调用。例如此时我们应用程序需要访问磁盘上的文件。此时应用程序就会调用系统调用的接口open方法,然后内核去访问磁盘中的文件,将文件内容返回给应用程序。大致的流程如下

直接缓冲区和非直接缓冲区

既然我们要读取一个磁盘的文件,要废这么大的周折。有没有什么简单的方法能够使我们的应用直接操作磁盘文件,不需要内核进行中转呢?有,那就是建立直接缓冲区了。

非直接缓冲区:非直接缓冲区就是我们上面所讲内核态作为中间人,每次都需要内核在中间作为中转。

直接缓冲区:直接缓冲区不需要内核空间作为中转copy数据,而是直接在物理内存申请一块空间,这块空间映射到内核地址空间和用户地址空间,应用程序与磁盘之间数据的存取通过这块直接申请的物理内存进行交互。

既然直接缓冲区那么快,我们为什么不都用直接缓冲区呢?其实直接缓冲区有以下的缺点。直接缓冲区的缺点:

  • 不安全

  • 消耗更多,因为它不是在JVM中直接开辟空间。这部分内存的回收只能依赖于垃圾回收机制,垃圾什么时候回收不受我们控制。

  • 数据写入物理内存缓冲区中,程序就丧失了对这些数据的管理,即什么时候这些数据被最终写入从磁盘只能由操作系统来决定,应用程序无法再干涉。

综上所述,所以我们使用transferTo方法就是直接开辟了一段直接缓冲区。所以性能相比而言提高了许多

使用内存映射文件

NIO中新出的另一个特性就是内存映射文件,内存映射文件为什么速度快呢?其实原因和上面所讲的一样,也是在内存中开辟了一段直接缓冲区。与数据直接作交互。源码如下

打印如下

可以看到速度和使用Channel的速度差不多的。

使用Pipe

Java NIO 管道是2个线程之间的单向数据连接。Pipe有一个source通道和一个sink通道。其中source通道用于读取数据,sink通道用于写入数据。可以看到源码中的介绍,大概意思就是写入线程会阻塞至有读线程从通道中读取数据。如果没有数据可读,读线程也会阻塞至写线程写入数据。直至通道关闭。

Whether or not a thread writing bytes to a pipe will block until another thread reads those bytes

我想要的效果是这样的。源码如下:

源码地址 https://github.com/modouxiansheng/Doraemon

总结

生活处处都需要学习,有时候只是一个简单的优化,可以让你深入学习到各种不同的知识。所以在学习中要不求甚解,不仅要知道这个知识也要了解为什么要这么做。

分享到:
评论

相关推荐

    MP3压缩工具将MP3压缩至1M左右

    在描述中提到的“非常简单的MP3压缩工具”可能是一个用户友好的界面,通过内置的算法自动调整压缩参数,如比特率、采样率等,以达到将MP3文件压缩到1M左右的目标。比特率是衡量音频质量的重要指标,通常以千比特每秒...

    30秒时长的无声音频

    本资源提供了一个30秒的无声音频,它包括两种常见的音频格式:m4a和mp3。让我们深入了解一下这两种格式以及它们在音频处理中的应用。 1. **M4A(MPEG-4音频层)**: - M4A是一种由Apple公司推广的音频文件格式,...

    飞鸽 局域网传送压缩文件包 文件夹最快的工具软件 速度最快能达20都M

    这款工具的最大亮点在于其传输速度,最高可以达到每秒20M,这意味着即便面对庞大的压缩文件,也能在短时间内完成传输,极大地提升了工作效率。 首先,我们来详细了解一下飞鸽在局域网文件传输中的优势。局域网...

    rar压缩软件.rar

    1) 从当前目录添加所有的 *.hlp 文件到 help.rar 压缩文件: rar a help *.hlp 2) 把当前目录和子目录的所有文件压缩为 362000 字节大小、固实的、 自解压分卷压缩文件并对没个卷添加恢复记录: rar a -r -v...

    强大的复制工具,370m文件只要10秒

    标题中的“强大的复制工具,370m文件只要10秒”揭示了这款软件在大文件复制方面的高效性能。在IT行业中,复制工具是经常被使用的实用程序,尤其是在需要频繁移动或备份大量数据时。这款工具能够以惊人的速度复制370...

    中文简体压缩软件RAR 6.0

    m[f] 移动到压缩文件中[只用于文件]。移动文件和目录会使压缩操作完成后它 们被删除。如果使用修正'f'和/或应用开关'-ed',则不删除目录。 p 打印文件到标准输出设备。 你可以把这个命令和 -inul 开关...

    1M带宽变4M带宽使你的网速更快

    标题“1M带宽变4M带宽使你的网速更快”以及描述“1M带宽变4M带宽这是个好软件哦”,暗示了一个软件或技术能将原本的1兆比特每秒(1Mbit/s)的带宽提升到4兆比特每秒(4Mbit/s),从而显著提高网络速度。下面我们将...

    压缩文件伪装在图片文件上传 JPF图片伪装工具 [免费版]

    压缩文件伪装在图片文件上传 JPF图片伪装工具 [免费版] 把压缩文件伪装在图片文件中把RAR文件伪装在JPG文件中,打开文件只是显示JPG图片,但把JPG文件...解决不能用中文目录,测试伪装一个185M用了1秒跟计算机有关。

    MPEG1-Layer-3.rar_MPEG layer 3 (.mp3)_compression mpeg mp3_音乐 压缩

    MPEG Layer 3压缩率可达1:10至1:12,1M的MP3文件可播放1分钟,而1分钟CD音质的WAV文件(44100Hz,16bit,双声道,60秒)要占用 10M空间,这样算来,一张650M的MP3光盘播放时间应在10小时以上,而同样容量的一张CD盘...

    高保真视频压缩限版2.3.7z

    最终效果是视频最大化的压缩...有时候我们录屏教别人东西时候:轻轻松松将80m录制好的视频压缩为5m视频发出去就可以了,画质还挺清晰的,压缩比十几倍吧。输出结果在本程序目录下。 压缩视频文件发送保存,保证画质。

    心电图信号压缩

    1. 转折点算法的目的是使心电信号的采样频率由200次/s减少到100次每秒。除了大振幅与陡峭的QRS复波外,对于ECG来说, 100次/s的采样速率是足够的。转折点算法基于以下认识:心电图信号一般被过分采样,其...

    1M带宽变4M带宽宽带加速

    压缩包子文件中的"1M带宽可变4M的东西宽带优化的最强武器.txt"可能包含更具体的优化技巧和软件推荐。这些文件通常会分享一些实用工具、设置建议或脚本,帮助用户进行网络优化。不过,需要注意的是,任何工具或方法都...

    WinRAR_4.0.exe

    1) 从当前目录添加所有的 *.hlp 文件到 help.rar 压缩文件: rar a help *.hlp 2) 把当前目录和子目录的所有文件压缩为 362000 字节大小、固实的、 自解压分卷压缩文件并对没个卷添加恢复记录: rar a -r -v...

    加密小金刚(压缩型)

    加密小金刚(压缩型)1.0特点: 它是一款免费软件,不做任何功能限制。... 它与加密小金刚5.0类似,他对处理的文件进行压缩,节约了用户的空间。... 七、高速处理多个文件,速度约5M/秒。密码长度不影响处理速度。

    关于 压缩算法的介绍

    MJPEG以其清晰的画质适用于特定的应用场景,而MPEG系列则通过不断的技术进步,实现了从VCD到DVD再到高清电视的飞跃,为用户提供更好的视觉体验。随着技术的发展,未来的压缩算法将会更加智能和高效,以满足不断增长...

    电脑之间快速传输软件,30M/S 左右的,相当于移动硬盘

    除此之外,还有一些专为游戏设计的高速传输工具,如`Steam`、`Epic Games Store`的游戏库同步功能,能快速将游戏文件从一台电脑复制到另一台,对于游戏玩家来说非常实用。 在实际使用过程中,为了确保数据传输的...

    8M数据抓包文件

    【标题】"8M数据抓包文件"是一个与网络数据包捕获相关的资源,它包含了一个8MB大小的PCAP(Packet Capture)文件和一个文本日志文件。PCAP文件是一种广泛使用的格式,用于存储网络流量的数据包记录,通常由抓包工具...

    MongoDB 3.0数据压缩测试.docx

    - 存储大小:数据文件248M + 索引文件87M - **MMAPv1引擎** - 单进程插入时间:12分钟59秒 - 多进程(4个进程)插入时间:3分钟37秒 - 存储大小:总计约4GB 从实验结果可以看出: - **插入速度**:无论是单进程...

    python_snappy-0.5.1-cp36-cp36m-win_amd64

    Snappy 比 zlib 更快,但文件相对要大 20% 到 100%。在 64位模式的 Core i7 处理器上,可达每秒 250~500兆的压缩速度。Snappy 在 Google 内部被广泛的使用,从 BigTable 到 MapReduce 以及内部的 RPC 系统。 snappy ...

    1080P、720P、4CIF、CIF所需要的理论带宽.doc

    例如,原始文件为88GB,采用MPEG-2压缩后为3.5GB,而采用H.264压缩后为1.1GB,从88GB到1.1GB,H.264的压缩比达到惊人的80∶1。 三、压缩后的带宽计算 在实际视频会议应用中,视频图像的数据量可以根据实际情况进行...

Global site tag (gtag.js) - Google Analytics