压缩算法---以golang/snappy为例

2023-09-14 21:01:06

压缩,典型的时间换空间

用到LRU,首选hashicorp/golang-lru,不过不知道啥时候,Go官方悄不溜整了一个groupcache,也提供了lru的实现…

顺道瞟了一眼,发现github.com/golang下除去有go,还有一整套配套的常用组件。比如vscode/sublime的插件,有性能测试工具perf,有错误处理库xerrors,有日志库glog,有用于单测的mock…甚至连压缩都提供了snappy,数据库有leveldb。。。这简直是想“自举”包圆整个产业链


golang/snappy[1]


snappy是Google研发的压缩算法,优点是有非常高的速度和合理的压缩率(压缩率比gzip 小)


package main

import (
 "fmt"
 "github.com/golang/snappy"
 "io/ioutil"
)

var (
 textMap = map[string]string{
  "a"`1234567890-=qwertyuiop[]\';lkjhgfdsazxcvbnm,./`,

  // a重复4次
  "b"`1234567890-=qwertyuiop[]\';lkjhgfdsazxcvbnm,./1234567890-=qwertyuiop[]\';lkjhgfdsazxcvbnm,./1234567890-=qwertyuiop[]\';lkjhgfdsazxcvbnm,./1234567890-=qwertyuiop[]\';lkjhgfdsazxcvbnm,./`,

  "c"`浕浉浄浀浂洉洡洣浐洘泚浌洼洽派洿浃浇浈浊测浍济浏浑浒浓浔泿洱涏洀洁洂洃洄洅洆洇洈洊洋洌洎洏洐洑洒洓洔洕洗洠洙洚洛洝洞洟洢洤津洦洧洨洩洪洫洬洭洮洲洳洴洵洶洷洸洹洺活涎`,

  // c重复3次
  "d"`浕浉浄浀浂洉洡洣浐洘泚浌洼洽派洿浃浇浈浊测浍济浏浑浒浓浔泿洱涏洀洁洂洃洄洅洆洇洈洊洋洌洎洏洐洑洒洓洔洕洗洠洙洚洛洝洞洟洢洤津洦洧洨洩洪洫洬洭洮洲洳洴洵洶洷洸洹洺活涎浕浉浄浀浂洉洡洣浐洘泚浌洼洽派洿浃浇浈浊测浍济浏浑浒浓浔泿洱涏洀洁洂洃洄洅洆洇洈洊洋洌洎洏洐洑洒洓洔洕洗洠洙洚洛洝洞洟洢洤津洦洧洨洩洪洫洬洭洮洲洳洴洵洶洷洸洹洺活涎浕浉浄浀浂洉洡洣浐洘泚浌洼洽派洿浃浇浈浊测浍济浏浑浒浓浔泿洱涏洀洁洂洃洄洅洆洇洈洊洋洌洎洏洐洑洒洓洔洕洗洠洙洚洛洝洞洟洢洤津洦洧洨洩洪洫洬洭洮洲洳洴洵洶洷洸洹洺活涎`,
 }

 imgSrc = []string{
  "john.jpg""Dijkstra.jpg""tony.jpg""tony1.jpg",
 }
)

/*
 k: a len: 46 48
 k: b len: 184 58
 k: c len: 246 250
 k: d len: 738 274
 snappy jpg
*/

func main() {
 for k, v := range textMap {
  got := snappy.Encode(nil, []byte(v))
  //fmt.Println("原始信息为:",v, "压缩后的信息为:",string(got))
  fmt.Println("k:", k, ", 原长度:"len(v), ", 压缩后的长度:"len(got))
 }

 fmt.Println("snappy压缩 jpg:")
 for _, v := range imgSrc {
  buf, err := ioutil.ReadFile(v)
  if err == nil {
   got := snappy.Encode(nil, buf)
   fmt.Println("k:", v, ", 原长度:"len(buf), ", 压缩后的长度:"len(got))
  }
 }
}

执行结果:

k: a , 原长度: 46 , 压缩后的长度: 48
k: b , 原长度: 184 , 压缩后的长度: 58
k: c , 原长度: 246 , 压缩后的长度: 250
k: d , 原长度: 738 , 压缩后的长度: 274
snappy压缩 jpg:
k: john.jpg , 原长度: 172909 , 压缩后的长度: 172921
k: Dijkstra.jpg , 原长度: 199459 , 压缩后的长度: 196799
k: tony.jpg , 原长度: 169282 , 压缩后的长度: 169026
k: tony1.jpg , 原长度: 52923 , 压缩后的长度: 52565

  • 字符串包含较多的重复字符,压缩才有较大效果

  • 对jpg 图片的压缩率不大,甚至还会使体积变大...


压缩 就是找出那些重复出现的字符串,然后用更短的符号代替。 如AAABBBBCC可以记为3A4B2C (只要保证对应关系,可以用任意字符代替那些重复出现的字符串)

所以对于没有重复的数据,无法再进一步压缩。 而文件需要加校验字段,所以对于没有重复信息的数据会越压越大

.jpg本身又已经经过了压缩(有损压缩),故而...

图片格式jpg、png、gif、RAW、TIFF有啥区别,图片受损没法打开,能修复吗?[2]


4张图片的原始信息如下:

alt

golang中snappy的使用场合实例详解[3]


其他的压缩算法


  • lz4[4]:综合来看效率最高的压缩算法,更侧重压缩/解压速度,压缩比并不是第一。当前Android和iOS操作系统,内存压缩就使用的是lz4算法,及时压缩内存以节省出更多的内存空间。 使用C编写. 更多 深入浅出lz4压缩算法[5]

  • zstd[6]: 由Facebook研发的快速数据压缩算法,具有更好的压缩比。使用C编写. 更多 zstd - 一种由Facebook使用的快速数据压缩算法[7]

  • zip:作者菲尔·卡茨[8],不愿意为一个压缩软件付钱,索性自己写了一个更好的算法ZIP,然后无偿公开。2000年4月14日,饮酒过量导致急性脾出血,死于一家汽车旅馆,年仅37岁,死时手中握着一个空酒瓶 更多ZIP,一个没落天才的故事[9]


alt

参考资料

[1]

golang/snappy: https://github.com/golang/snappy

[2]

图片格式jpg、png、gif、RAW、TIFF有啥区别,图片受损没法打开,能修复吗?: https://www.sohu.com/a/485790854_120293876

[3]

golang中snappy的使用场合实例详解: jb51.net/article/130763.htm

[4]

lz4: https://github.com/lz4/lz4

[5]

深入浅出lz4压缩算法: https://www.jianshu.com/p/824e1cf4f920

[6]

zstd: https://github.com/facebook/zstd

[7]

zstd - 一种由Facebook使用的快速数据压缩算法: https://www.howtoing.com/zstd-fast-data-compression-algorithm-used-by-facebook

[8]

菲尔·卡茨: https://zh.wikipedia.org/wiki/%E8%8F%B2%E5%B0%94%C2%B7%E5%8D%A1%E8%8C%A8

[9]

ZIP,一个没落天才的故事: https://www.cnbeta.com/articles/tech/185863.htm

本文由 mdnice 多平台发布

更多推荐

视频转漫画怎么转?分享三个简单便捷的操作

在现代社会,人们对于视频和漫画的需求越来越多,而将视频转换为漫画则是一种新的趋势。本文将分享三个简单便捷的操作方式和注意事项,以帮助读者更好地进行视频转漫画的操作。操作方式一:使用手机转换工具对于经常使用手机来比编辑图片或视频的小伙伴我们可以使用书单视频助手来把视频转成漫画效果,我们打开这款工具后,然后在热门工具板块中

Vue 2 进入、离开和列表过渡

前言Vue提供了多种方式来实现过渡效果。在CSS过渡和动画中自动应用class配合CSS动画库在过渡钩子函数中使用JavaScript操作DOM配合JavaScript动画库单元素/组件的过渡将元素或组件放在<transition>中可以在下列情形中触发过渡效果:使用了v-if使用了v-show使用了动态组件组件根节点

JVM:常见的垃圾回收算法

常见的垃圾回收算法分代收集理论当前商业虚拟机的垃圾收集器,大多数都遵循了“分代收集”(GenerationalCollection)[1]的理论进行设计,分代收集名为理论,实质是一套符合大多数程序运行实际情况的经验法则。1)经验法则1:绝大多数对象都是朝生夕灭的。2)经验法则2:熬过越多次垃圾收集过程的对象就越难以消亡

BD就业复习第二天

Hbase1.架构HBase(HadoopDatabase)是一个开源的分布式、面向列族(ColumnFamily)的NoSQL数据库,它是构建在Hadoop之上的。HBase的架构设计旨在处理大规模的数据,特别适用于需要快速读写和随机访问大量数据的应用场景,如日志处理、在线实时分析等。下面是HBase的详细架构解析:

POI的读取EXCEL的【总结】

POI的读取EXcel的总结最近的自己在做了一些关于EXcel的导入工作,正好总结一下我用到一些知识点我首先说用到的方法POI读取指定行列的方法语法:sheet.getRow(x):获取第x行sheet.getRow(x).getCell(y):获取第x行第y列eg:sheet.getRow(5).getCell(2)

Redis的缓存雪崩、缓存穿透、缓存击穿

1.redis的优点高性能:redis是基于内存的数据库,数据存储在RAM中,读写速度很快数据持久化:能够将内存中的数据保存咋磁盘上,防止数据丢失;两种持久化方式:快照和日志追加形式简单丰富:支持丰富的数据类型和易于使用的API2.redis的缺点内存限制:redis存储在内存中,因此受可用内存大小的限制单线程模型:r

Vue中的深度监听(Deep Watch):详细解析与实际示例

Vue中的深度监听(DeepWatch):详细解析与实际示例Vue.js是一款流行的前端JavaScript框架,其响应式系统是其核心特性之一。通过响应式系统,Vue允许开发者轻松地监听数据的变化并对其做出响应。在某些情况下,你可能需要对嵌套的数据结构进行深度监听,以便在任何级别的数据变化时触发相应的操作。本文将深入探

HTML5 Canvas动画实例

在开发在线游戏时,绘制动画是非常重要的。本文介绍一个使用CanvasAPI实现的动画实例——游戏人物的跑步动画。01、动画的概念及原理1、动画动画是通过一幅幅静止的、内容不同的画面(即帧)快速播放来呈现的,使人们在视觉上产生动的感觉。这是利用了人类眼睛的视觉暂留原理。利用人的这种生理特性可制作出具有高度想象力和表现力的

Matlab论文插图绘制模板第115期—带Latex公式的图

之前的文章中,分享了Matlab带线标记的图:带阴影标记的图:带箭头标记的图:带图形标记的图:进一步,分享一下带Latex公式的图,先来看一下成品效果:特别提示:本期内容『数据+代码』已上传资源群中,加群的朋友请自行下载。有需要的朋友可以关注同名公号【阿昆的科研日常】,后台回复关键词【绘图桶】查看加入方式。模板中最关键

代码随想录算法训练营第三十七天|738.单调递增的数字 968.监控二叉树 总结

738.单调递增的数字代码随想录例如:98,一旦出现strNum[i-1]>strNum[i]的情况(非单调递增),首先想让strNum[i-1]--,然后strNum[i]给为9,这样这个整数就是89,即小于98的最大的单调递增整数。从前向后遍历的话,遇到strNum[i-1]>strNum[i]的情况,让strNu

openjdk和oracle jdk的区别

OpenJDK和OracleJDK都是JavaDevelopmentKit(JDK)的不同实现,用于开发和运行Java应用程序。它们有一些区别,但也有很多相似之处。以下是它们之间的主要区别:开源性质:OpenJDK是开源的,由一个社区维护和开发,它的源代码可以在OpenJDK项目的网站上找到。这意味着任何人都可以免费获

热文推荐