适用于嵌入式单片机的压缩算法
1. 简介
因为MCU的内存和算力的限制,那些对内存消耗大或算力需求大的压缩算法就不适合在MCU中使用。适用于MCU的压缩算法主要有:RLE、LZ77、Huffman、LZO、DEFLATE、LZ4。
2. 算法
2.1. RLE
RLE(Run Length Encoding),也称为行程编码,压缩算法是一种无损压缩算法。算法特点:简单、易实现。使用RLE压缩方法可以将 RRRRRGGBBBBBBABCD 压缩为 5R2G6B1A1B1C1D。基于RLE算法升级,可以将RRRRRGGBBBBBBABCD可以压缩为b’\x85R\x82G\x86B\x03ABCD’,0x85表示后面有5个相同的字符,0x03表示后面有3个不连续的字符。
RLE的实现非常简单,针对一些图片颜色少或重复字符多的文件有非常好的压缩率,RLE的适用场景比较少,通用压缩率较差。
2.2. LZ77
LZ77是一种基于字典的算法,它将长字符串(也称为短语)编码成短小的标记,用小标记代替字典中的短语,从而达到压缩的目的。LZ77算法的压缩率、速度、内存消费都是中等,但是代码复杂度较低,适用于MCU的使用。
2.3. LZO
LZO压缩算法采用(重复长度L,指回距离D)代替当前已经在历史字符串中出现过的字符串。LZO致力于解压速度,不同的参数下的LZO压缩率不同。LZO内存消耗中等,解压速度较快,压缩速度较快,但是代码复杂度较低,适用于Bootloader等追求压缩率和解压速度的场景。
2.4. Huffman
霍夫曼(Huffman)编码使用变长编码表对源符号进行编码,其中变长编码表是通过一种评估来源符号出现机率的方法得到的,出现机率高的字母使用较短的编码,反之出现机率低的则使用较长的编码,这便使编码之后的字符串的平均长度、期望值降低,从而达到无损压缩数据的目的。霍夫曼编码使用的编码表,使用霍夫曼树来进行存储,让出现概率最高的编码最容易查找,以提升解码速度。霍夫曼编码算法的压缩率分布在20%-90%,因为要扫描整个数据来构建霍夫曼树,所以其压缩速度较慢,且需要一定的内存来存储编码表,但是解压速度较快。霍夫曼的算法复杂度较简单。
2.5. DEFLATE
DEFLATE是同时使用了LZ77算法与哈夫曼编码(Huffman Coding)的一个无损数据压缩算法。DEFLATE压缩与解代码可以在自由、通用的压缩库zlib上找到。DEFLATE算法压缩速度、解压速度均处于中等,却有着比较好的压缩率,所以是zlib、gzip使用的主要压缩算法。DEFLATE的算法复杂度较高,但是性能表现优秀,适用于比较大型的MCU系统。
2.6. LZ4
LZ4是一种LZ系列压缩算法,着重于压缩和解压的速度,压缩率相对较低。LZ4压缩率较低,算法复杂度和内存消耗中等,但是压缩和解压速度,尤其是解压速度远超其他算法。因为其综合性能优秀,在Linux、Android中的内存压缩技术一般使用LZ4压缩算法。LZ4 HC,有着更好的压缩率,但是算法复杂度大幅提升,且压缩速度也大幅减慢,但是依然有着很好的解压速度,适合Bootloader这种应用场景。LZ4的内存消耗从几百字节到几十K字节。
3. 基准测试
3.1. 工具用法
- RLE
● 测试文件
I:\Linux>RLE.exe d:\a.exe
d:\a.exe
Orignal Size:132096-Compressed Size:125400
Compressed rate:94%
● 测试目录
I:\Linux>RLE.exe E:\ATLDemo\Demo\Debug
E:\ATLDemo\Demo\Debug\ATLProject1.exe
Orignal Size:9160192-Compressed Size:7105584
Compressed rate:77%
E:\ATLDemo\Demo\Debug\ATLProject1.map
Orignal Size:19710649-Compressed Size:16943928
Compressed rate:85%
- Huffman
● 测试文件
I:\Linux>Huffman.exe d:\a.exe
d:\a.exe
Orignal Size:132096-Compressed Size:123772
Compressed rate:93%
● 测试目录
I:\Linux>Huffman.exe E:\ATLDemo\Demo\Debug
E:\ATLDemo\Demo\Debug\ATLProject1.exe
Orignal Size:9160192-Compressed Size:7695483
Compressed rate:84%
E:\ATLDemo\Demo\Debug\ATLProject1.map
Orignal Size:19710649-Compressed Size:15878850
Compressed rate:80%
- LZ77
I:\Linux>lzbench18.exe -elz4 d:\a.exe
lzbench 1.8 (64-bit Windows) Assembled by P.Skibinski
Compressor name Compress. Decompress. Compr. size Ratio Filename
memcpy 35490 MB/s 35924 MB/s 132096 100.00 a.exe
lz4 1.9.2 616 MB/s 4388 MB/s 91011 68.90 a.exe
done... (cIters=1 dIters=1 cTime=1.0 dTime=2.0 chunkSize=1706MB cSpeed=0MB)
- LZO
I:\Linux>lzbench18.exe -elzo1 d:\a.exe
lzbench 1.8 (64-bit Windows) Assembled by P.Skibinski
Compressor name Compress. Decompress. Compr. size Ratio Filename
memcpy 35442 MB/s 36160 MB/s 132096 100.00 a.exe
lzo1 2.10 -1 150 MB/s 433 MB/s 90130 68.23 a.exe
lzo1 2.10 -99 70 MB/s 415 MB/s 85293 64.57 a.exe
done... (cIters=1 dIters=1 cTime=1.0 dTime=2.0 chunkSize=1706MB cSpeed=0MB)
- LZ4
I:\Linux>lzbench18.exe -elz4 d:\a.exe
lzbench 1.8 (64-bit Windows) Assembled by P.Skibinski
Compressor name Compress. Decompress. Compr. size Ratio Filename
memcpy 35085 MB/s 34689 MB/s 132096 100.00 a.exe
lz4 1.9.2 615 MB/s 4388 MB/s 91011 68.90 a.exe
done... (cIters=1 dIters=1 cTime=1.0 dTime=2.0 chunkSize=1706MB cSpeed=0MB)
I:\Linux>lzbench18.exe -elz4hc d:\a.exe
lzbench 1.8 (64-bit Windows) Assembled by P.Skibinski
Compressor name Compress. Decompress. Compr. size Ratio Filename
memcpy 34462 MB/s 35944 MB/s 132096 100.00 a.exe
lz4hc 1.9.2 -1 79 MB/s 3851 MB/s 81847 61.96 a.exe
lz4hc 1.9.2 -2 79 MB/s 3840 MB/s 81847 61.96 a.exe
lz4hc 1.9.2 -3 69 MB/s 3862 MB/s 81207 61.48 a.exe
lz4hc 1.9.2 -4 63 MB/s 3885 MB/s 80896 61.24 a.exe
lz4hc 1.9.2 -5 59 MB/s 3885 MB/s 80750 61.13 a.exe
lz4hc 1.9.2 -6 56 MB/s 3896 MB/s 80650 61.05 a.exe
lz4hc 1.9.2 -7 53 MB/s 3908 MB/s 80604 61.02 a.exe
lz4hc 1.9.2 -8 51 MB/s 3919 MB/s 80586 61.01 a.exe
lz4hc 1.9.2 -9 47 MB/s 3943 MB/s 80568 60.99 a.exe
lz4hc 1.9.2 -10 29 MB/s 3919 MB/s 80454 60.91 a.exe
lz4hc 1.9.2 -11 22 MB/s 3931 MB/s 80442 60.90 a.exe
lz4hc 1.9.2 -12 20 MB/s 3896 MB/s 80420 60.88 a.exe
done... (cIters=1 dIters=1 cTime=1.0 dTime=2.0 chunkSize=1706MB cSpeed=0MB)
- DEFLATE
I:\Linux>lzbench18.exe -elibdeflate d:\a.exe
lzbench 1.8 (64-bit Windows) Assembled by P.Skibinski
Compressor name Compress. Decompress. Compr. size Ratio Filename
memcpy 35711 MB/s 36420 MB/s 132096 100.00 a.exe
libdeflate 1.3 -1 92 MB/s 382 MB/s 69917 52.93 a.exe
libdeflate 1.3 -2 88 MB/s 387 MB/s 69425 52.56 a.exe
libdeflate 1.3 -3 85 MB/s 391 MB/s 69207 52.39 a.exe
libdeflate 1.3 -4 81 MB/s 394 MB/s 69085 52.30 a.exe
libdeflate 1.3 -5 70 MB/s 411 MB/s 68098 51.55 a.exe
libdeflate 1.3 -6 67 MB/s 408 MB/s 68034 51.50 a.exe
libdeflate 1.3 -7 62 MB/s 409 MB/s 67972 51.46 a.exe
libdeflate 1.3 -8 22 MB/s 413 MB/s 67138 50.83 a.exe
libdeflate 1.3 -9 17 MB/s 403 MB/s 66693 50.49 a.exe
libdeflate 1.3 -10 16 MB/s 401 MB/s 66627 50.44 a.exe
libdeflate 1.3 -11 13 MB/s 400 MB/s 66604 50.42 a.exe
libdeflate 1.3 -12 10 MB/s 407 MB/s 66598 50.42 a.exe
done... (cIters=1 dIters=1 cTime=1.0 dTime=2.0 chunkSize=1706MB cSpeed=0MB)
3.2. 脚本测试
脚本是基于Cygwin环境执行的shell脚本。用法如下:
26/01/2024 11:15.41/drives/i/Linux/compression_test.sh
请输入待测目录:
e:\ATLDemototal size 297101065 , total compressed size: 210777636
RLE compression rate: 70%total size 297101065 , total compressed size: 205327668
Huffman compression rate: 69%total size 297059235 , total compressed size: 109202247
LZ4 compression rate: 36%total size 296918510 , total compressed size: 115966722
LZO compression rate: 39%
4. 总结
4.1. 性能
● 综合压缩率排名:DEFLATE > LZ4HC > LZO > LZ77 > Huffman > LZ4 >> RLE。
● 压缩速度排名:LZ4 > LZO > RLE > LZ77 > DEFLATE > Huffman > LZ4HC。
● 解压速度排名:RLE > LZ4=LZ4HC >> Huffman > LZO > DEFLATE > LZ77。
● 算法复杂度排名:RLE < Huffman < LZ77 < LZ4 < LZO < LZ4HC < DEFLATE。
● 算法内存消耗排名:RLE < LZ4 < LZO < LZ77 < Huffman < DEFLATE < LZ4 HC。
4.2. 应用场景
不同的压缩算法,有不同的应用场景。
- 高压缩率,压缩速度慢,但是解压速度快的算法,适用于Bootloader。高压缩率,可以节省ROM空间,高解压速度对Boot速度影响小。因为是外部工具压缩,压缩速度不影响Bootloader的功能。适用于此场景的压缩算法有lzo、lz4hc。
- 追求压缩率,且算力和内存资源充足,并且压缩和解压均不错的算法,选择DEFLATE。
- 有一定的压缩率(50%),追求压缩和解压速度,且算法相对简单,优先LZ4,再选择LZ77,再先LZO.
- 在一定的压缩率(50%)的基础上,追求算法简单,优先LZ77。
4.3. LZ77 vs LZ4
● 如果LZ77的算法复杂度为100,则LZ4的为130。压缩和解压C代码,LZ77在400行左右,LZ4在500行左右。
● 如果LZ77的内存消耗为100,则LZ4的内存消耗为50。LZ77的内存消耗十几K到几十K,LZ4的内存从几百字节到十几K字节。
● 如果LZ77的压缩速度为100,则LZ4的压缩速度为700。
● 如果LZ77的解压速度为100,则LZ4的解压速度为800。
总结,LZ4的综合性能远优于LZ77。这也是LZ4应用于Linux和Android内存压缩的重要原因。
4.3. 代码
代码
相关文章:
适用于嵌入式单片机的压缩算法
1. 简介 因为MCU的内存和算力的限制,那些对内存消耗大或算力需求大的压缩算法就不适合在MCU中使用。适用于MCU的压缩算法主要有:RLE、LZ77、Huffman、LZO、DEFLATE、LZ4。 2. 算法 2.1. RLE RLE(Run Length Encoding),也称为行程编码&…...
软件工程(最简式总结)
目录 第一章:概述 1.软件危机的表现原因 2.常见的软件开发方法包括: 3.软件工程基本原则 4.软件工程三要素 5.设计模式的分类 6.针对变换型数据流设计步骤 7.针对事务型数据流设计步骤 第二章:软件过程 1.软件生命周期 2.软件过程模型 &…...
Docker基础(持续更新中)
# 第1步,去DockerHub查看nginx镜像仓库及相关信息# 第2步,拉取Nginx镜像 docker pull nginx# 第3步,查看镜像 docker images # 结果如下: REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 60…...
Vue工程引入Element-ui
npm 安装ELement-ui npm i element-ui -S 于package.json中发现有“element-ui”版本号即可 引入 Element 在 main.js 中写入以下内容: import element-ui/lib/theme-chalk/index.css; import ElementUI from element-ui;Vue.use(ElementUI);之后根据自己的需求设计…...
算法学习——华为机考题库9(HJ56 - HJ63)
算法学习——华为机考题库9(HJ56 - HJ63) HJ56 完全数计算 描述 完全数(Perfect number),又称完美数或完备数,是一些特殊的自然数。 它所有的真因子(即除了自身以外的约数)的和&…...
Maven安装,学习笔记,详细整理maven的一些配置
Maven 1. 初识Maven 2. Maven概述 Maven模型介绍 Maven仓库介绍 Maven安装与配置 3. IDEA集成Maven 4. 依赖管理 01. Maven课程介绍 1.1 课程安排 学习完前端Web开发技术后,我们即将开始学习后端Web开发技术。做为一名Java开发工程师,后端 Web开发技术…...
STM32--USART串口(2)串口外设
一、USART简介 可配置数据位:不需要校验就是8位,需要校验就选9位; 停止位:决定了帧的间隔; STM32F103C8T6USART:USART1挂载在APB2总线上,USART2和USART3挂载在APB1总线上; 二、USART框图 TXE…...
Unity之做一个最简单的FPS游戏demo
目录 😋FPS游戏Demo 💤1.新建FPS模板项目 ⚒️2.装备枪 💣3.设置射击功能 📺4.制造一个子弹预制体 🎮5.发射子弹 说起来小编学Unity差不多一个月了,都是利用上班摸鱼时间学的(doge.jpg&…...
【Springboot】单元测试Junit5应用
JUnit 5是一个功能强大的测试框架,常用于编写和执行这些单元测试。以下是一些JUnit 5中的常用注解、断言、前置条件、嵌套测试和参数化测试的例子: 1.环境启动 SpringBootTest 注解: classes SmartApplication.class:这个属性…...
【INTEL(ALTERA)】内部错误:子系统:PTI,文件:/quartus/tsm/pti/pti_delay_annotator.cpp
说明 由于英特尔 Quartus Prime Pro Edition 软件 23.2 及更早版本存在问题,因此在编译设计的 Retime 期间可能会出现此错误。 解决方法 此问题已在英特尔 Quartus Prime Pro Edition 软件 v23.3 中修复。 要在版本 23.2 中解决此问题,请通过以下相应链…...
大数据 - Spark系列《二》- 关于Spark在Idea中的一些常用配置
上一篇: 大数据 - Spark系列《一》- 从Hadoop到Spark:大数据计算引擎的演进-CSDN博客 目录 1. 🥙Idea中配置Live Templates来快速生成代码片段 2. 🥙Idea中配置文件模板自定义初始代码 3.🥙设置spark-submit提交程…...
android 设置未知来源等 AppOpsManager 权限的设置接口
开始客户让我们执行下面的CMD 代码 adb shell appops set com.android.chrome REQUEST_INSTALL_PACKAGES allow 后来 GTP 告诉我有 Setmode的方法,后面在设置里面找到了 OP_REQUEST_INSTALL_PACKAGES 这个,里面有个方法mAppOpsManager.setMode(AppOp…...
使用GPT实现一个简单的网站
背景 In this exciting tutorial video, you’ll discover how to use 文心一言, a powerful language model developed by 百度, to generate ReactJS code for a simple blog website. With 文心一言’s help, you can quickly create a blog website that’s easy to custom…...
回归预测 | Matlab实现CPO-CNN-LSTM-Attention冠豪猪优化卷积长短期记忆神经网络注意力机制多变量回归预测(SE注意力机制)
回归预测 | Matlab实现CPO-CNN-LSTM-Attention冠豪猪优化卷积长短期记忆神经网络注意力机制多变量回归预测(SE注意力机制) 目录 回归预测 | Matlab实现CPO-CNN-LSTM-Attention冠豪猪优化卷积长短期记忆神经网络注意力机制多变量回归预测(SE注…...
11:Servlet中初始化参数的获取与应用-Java Web
目录 11.1 Servlet初始化参数简介11.2 如何在Servlet中获取初始化参数11.3 基于注解的初始化参数(Servlet 3.0)11.4 区别总结11.5 应用场景总结 在构建Java Web应用程序时,Servlet是核心组件之一,它负责处理HTTP请求并生成响应。而…...
STM32的ADC采集传感器的模拟量数据
1、 由于项目上使用传感器采集数据,传感器可以输出模拟电压信号,但是模拟电压信号的输出范围是1-5V,而STM32的ADC采集电压范围是0-3.3V,此时可以用一个简单的分压电路将1-5V的电压将至0.5V到2.5V的范围。 2、电阻分压电路可以使用…...
opencvb 十七 使用cmake配置opencv c++项目
1、cmake简介 1.1 cmake是什么 CMake是一个开源、跨平台的编译(Build)工具,是用来构建、测试和打包软件的。它能够用简单的语句来描述所有平台的编译过程。它能够输出各种各样的makefile或者project文件,能测试编译器所支持的C特…...
Java8 中文指南(一)
Java8 中文指南(一) 文章目录 Java8 中文指南(一)《Java8 指南》中文翻译接口的默认方法(Default Methods for Interfaces)Lambda 表达式(Lambda expressions)函数式接口(Functional Interfaces)方法和构造函数引用(Method and Co…...
引流技术-通过文件中增加联系方式并传播
文章目录 前言文档增加联系方式扩散网盘扩散自建网站借力 注意 前言 很多人在找资料的时候可能都遇到过下图情况: 1、文档最后面留一个自己的联系方式; 2、找的一堆文件中都有相同的情况; 3、一段时间全网搜到的很多相同文件也有这个联系方式…...
分布式搜索引擎_学习笔记_2
分布式搜索引擎_学习笔记_2 在昨天的学习中,我们已经导入了大量数据到elasticsearch中,实现了elasticsearch的数据存储功能。但elasticsearch最擅长的还是搜索和数据分析。 所以今天,我们研究下elasticsearch的数据搜索功能。我们会分别使用…...
(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
