字符串压缩(三)之短字符串压缩

2023-11-01

一、通用算法的短字符压缩

  开门见山,我们使用一段比较短的文本:Narrator: It is raining today. So, Peppa and George cannot  play outside.Peppa: Daddy, it's stopped raining.

  使用ZSTD与LZ4分别压缩一下上面这段短文本。下面分别是它们的压缩结果。

  ZSTD:

  

   LZ4:

  

  对短文本的压缩,zstd的压缩率很低,lz4压缩后的文本长度尽然超过了原有字符串的长度。这是为什么?说实话在这之前我也没想到。

  引用两位大佬的名言:

  Are you ok?  

  What's your problem?

二、短字符串压缩

  从上面的结果可以得知,任何压缩算法都有它的使用场景,并不是所有长度的字符串都适合被某种算法压缩。一般原因是通用压缩算法维护了被压缩字符串的,用于字符串还原的相关数据结构,而这些数据结构的长度超过了被压缩短字符串的自身长度。

  那么问题来了,“我真的有压缩短字符串的需求,我想体验压缩的极致感,怎么办?”。

  短字符压缩算法它来了。这里挑选了3种比较优异的短字符压缩算法,分别是smaz,shoco,以及压轴的unisox2。跟前两章一样,还是从压缩率,压缩和解压缩性能的角度,一起看看他们在短字符压缩场景的各自表现吧。

(1)Smaz

1、Smaz的压缩和解压缩

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <iostream>
 4 #include "smaz.h"
 5 
 6 using namespace std;
 7 
 8 int main()
 9 {
10     int buf_len;
11     int com_size;
12     int decom_size;
13     
14     char com_buf[4096] = {0};
15     char decom_buf[4096] = {0};
16 
17     char str_buf[1024] = "Narrator: It is raining today. So, Peppa and George cannot play outside.Peppa: Daddy, it's stopped raining.";
18 
19     buf_len = strlen(str_buf);
20     com_size = smaz_compress(str_buf, buf_len, com_buf, 4096);
21     
22     cout << "text size:" << buf_len << endl;
23     cout << "compress text size:" << com_size << endl;
24     cout << "compress ratio:" << (float)buf_len / (float)com_size << endl << endl;
25 
26     decom_size = smaz_decompress(com_buf, com_size, decom_buf, 4096);
27     cout << "decompress text size:" << decom_size << endl;
28 
29     if(strncmp(str_buf, decom_buf, buf_len)) {
30         cout << "decompress text is not equal to source text" << endl;
31     }
32 
33     return 0;
34 }

  执行结果如下:

   

   通过smaz压缩后的短字符串长度为77,和源字符串相比,减少了30Byte。

2、Smaz的压缩和解压缩性能

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <iostream>
 4 #include <sys/time.h>
 5 #include "smaz.h"
 6 
 7 using namespace std;
 8 
 9 int main()
10 {
11     int cnt = 0;
12     int buf_len;
13     int com_size;
14     int decom_size;
15 
16     timeval st, et;
17     
18     char *com_ptr = NULL;
19     char* decom_ptr = NULL;
20 
21     char str_buf[1024] = "Narrator: It is raining today. So, Peppa and George cannot play outside.Peppa: Daddy, it's stopped raining.";
22 
23     buf_len = strlen(str_buf);
24     gettimeofday(&st, NULL);
25     while(1) {
26         
27         com_ptr = (char *)malloc(buf_len);
28         com_size = smaz_compress(str_buf, buf_len, com_ptr, buf_len);
29 
30         free(com_ptr);
31         cnt++;
32         
33         gettimeofday(&et, NULL);
34         if(et.tv_sec - st.tv_sec >= 10) {
35             break;
36         }
37     }
38 
39     cout << endl <<"compress per second:" << cnt/10 << " times" << endl;
40 
41     cnt = 0;
42     com_ptr = (char *)malloc(buf_len);
43     com_size = smaz_compress(str_buf, buf_len, com_ptr, buf_len);
44     
45     gettimeofday(&st, NULL);
46     while(1) {
47 
48         // decompress length not more than origin buf length
49         decom_ptr = (char *)malloc(buf_len + 1);
50         decom_size = smaz_decompress(com_ptr, com_size, decom_ptr, buf_len + 1);
51 
52         // check decompress length
53         if(buf_len != decom_size) {
54             cout << "decom error" << endl;
55         }
56         
57         free(decom_ptr);
58         cnt++;
59         
60         gettimeofday(&et, NULL);
61         if(et.tv_sec - st.tv_sec >= 10) {
62             break;
63         }
64     }
65 
66     cout << "decompress per second:" << cnt/10 << " times" << endl << endl;
67     
68     free(com_ptr);
69     return 0;
70 }

  结果如何?

  

   压缩性能在40w条/S,解压在百万级,好像还不错哈!

(2)Shoco

1、Shoco的压缩和解压缩

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <iostream>
 4 #include "shoco.h"
 5 
 6 using namespace std;
 7 
 8 int main()
 9 {
10     int buf_len;
11     int com_size;
12     int decom_size;
13     
14     char com_buf[4096] = {0};
15     char decom_buf[4096] = {0};
16 
17     char str_buf[1024] = "Narrator: It is raining today. So, Peppa and George cannot play outside.Peppa: Daddy, it's stopped raining.";
18 
19     buf_len = strlen(str_buf);
20     com_size = shoco_compress(str_buf, buf_len, com_buf, 4096);
21     
22     cout << "text size:" << buf_len << endl;
23     cout << "compress text size:" << com_size << endl;
24     cout << "compress ratio:" << (float)buf_len / (float)com_size << endl << endl;
25 
26     decom_size = shoco_decompress(com_buf, com_size, decom_buf, 4096);
27     cout << "decompress text size:" << decom_size << endl;
28 
29     if(strncmp(str_buf, decom_buf, buf_len)) {
30         cout << "decompress text is not equal to source text" << endl;
31     }
32 
33     return 0;
34 }

  执行结果如下:

  

   通过shoco压缩后的短字符串长度为86,和源字符串相比,减少了21Byte。压缩率比smaz要低。

 2、Shoco的压缩和解压缩性能

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <iostream>
 4 #include <sys/time.h>
 5 #include "shoco.h"
 6 
 7 using namespace std;
 8 
 9 int main()
10 {
11     int cnt = 0;
12     int buf_len;
13     int com_size;
14     int decom_size;
15 
16     timeval st, et;
17     
18     char *com_ptr = NULL;
19     char* decom_ptr = NULL;
20 
21     char str_buf[1024] = "Narrator: It is raining today. So, Peppa and George cannot play outside.Peppa: Daddy, it's stopped raining.";
22 
23     buf_len = strlen(str_buf);
24     gettimeofday(&st, NULL);
25     while(1) {
26         
27         com_ptr = (char *)malloc(buf_len);
28         com_size = shoco_compress(str_buf, buf_len, com_ptr, buf_len);
29 
30         free(com_ptr);
31         cnt++;
32         
33         gettimeofday(&et, NULL);
34         if(et.tv_sec - st.tv_sec >= 10) {
35             break;
36         }
37     }
38 
39     cout << endl <<"compress per second:" << cnt/10 << " times" << endl;
40 
41     cnt = 0;
42     com_ptr = (char *)malloc(buf_len);
43     com_size = shoco_compress(str_buf, buf_len, com_ptr, buf_len);
44     
45     gettimeofday(&st, NULL);
46     while(1) {
47 
48         // decompress length not more than origin buf length
49         decom_ptr = (char *)malloc(buf_len + 1);
50         decom_size = shoco_decompress(com_ptr, com_size, decom_ptr, buf_len + 1);
51 
52         // check decompress length
53         if(buf_len != decom_size) {
54             cout << "decom error" << endl;
55         }
56         
57         free(decom_ptr);
58         cnt++;
59         
60         gettimeofday(&et, NULL);
61         if(et.tv_sec - st.tv_sec >= 10) {
62             break;
63         }
64     }
65 
66     cout << "decompress per second:" << cnt/10 << " times" << endl << endl;
67     
68     free(com_ptr);
69     return 0;
70 }

  执行结果如何呢?

  

   holy shit!压缩和解压缩居然都达到了惊人的百万级。就像算法作者们自己说的一样:“在长字符串压缩领域,shoco不想与通用压缩算法竞争,我们的优势是短字符的快速压缩,虽然压缩率很烂!”。这样说,好像也没毛病。

(3)Unisox2

  我们再来看看unisox2呢。

1、Unisox2的压缩和解压缩

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include "unishox2.h"
 4 
 5 int main()
 6 {
 7     int buf_len;
 8     int com_size;
 9     int decom_size;
10     
11     char com_buf[4096] = {0};
12     char decom_buf[4096] = {0};
13     
14     char str_buf[1024] = "Narrator: It is raining today. So, Peppa and George cannot play outside.Peppa: Daddy, it's stopped raining.";
15     
16     buf_len = strlen(str_buf);
17     com_size = unishox2_compress_simple(str_buf, buf_len, com_buf);
18 
19     printf("text size:%d\n", buf_len);
20     printf("compress text size:%d\n", com_size);
21     printf("compress ratio:%f\n\n", (float)buf_len / (float)com_size);
22     
23     decom_size = unishox2_decompress_simple(com_buf, com_size, decom_buf);
24 
25     printf("decompress text size:%d\n", decom_size);
26 
27     if(strncmp(str_buf, decom_buf, buf_len)) {
28         printf("decompress text is not equal to source text\n");
29     }
30 
31     return 0;
32 }

  结果如下:

  

   通过Unisox2压缩后的短字符串长度为67,和源字符串相比,减少了40Byte,相当于是打了6折啊!不错不错。

 2、Unisox2的压缩和解压缩性能

  Unisox2的压缩能力目前来看是三者中最好的,如果他的压缩和解压性能也不错的话,那就真的就比较完美了。再一起看看Unisox2的压缩和解压性能吧!

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <malloc.h>
 4 #include <sys/time.h>
 5 #include "unishox2.h"
 6 
 7 int main()
 8 {
 9     int cnt = 0;
10     int buf_len;
11     int com_size;
12     int decom_size;
13 
14     struct timeval st, et;
15     
16     char *com_ptr = NULL;
17     char* decom_ptr = NULL;
18 
19     char str_buf[1024] = "Narrator: It is raining today. So, Peppa and George cannot play outside.Peppa: Daddy, it's stopped raining.";
20 
21     buf_len = strlen(str_buf);
22     gettimeofday(&st, NULL);
23     while(1) {
24         
25         com_ptr = (char *)malloc(buf_len);
26         com_size = unishox2_compress_simple(str_buf, buf_len, com_ptr);
27 
28         free(com_ptr);
29         cnt++;
30         
31         gettimeofday(&et, NULL);
32         if(et.tv_sec - st.tv_sec >= 10) {
33             break;
34         }
35     }
36 
37     printf("\ncompress per second:%d times\n", cnt/10);
38 
39     cnt = 0;
40     com_ptr = (char *)malloc(buf_len);
41     com_size = unishox2_compress_simple(str_buf, buf_len, com_ptr);
42     
43     gettimeofday(&st, NULL);
44     while(1) {
45 
46         // decompress length not more than origin buf length
47         decom_ptr = (char *)malloc(buf_len + 1);
48         decom_size = unishox2_decompress_simple(com_ptr, com_size, decom_ptr);
49 
50         // check decompress length
51         if(buf_len != decom_size) {
52             printf("decom error\n");
53         }
54         
55         free(decom_ptr);
56         cnt++;
57         
58         gettimeofday(&et, NULL);
59         if(et.tv_sec - st.tv_sec >= 10) {
60             break;
61         }
62     }
63 
64     printf("decompress per second:%d times\n\n", cnt/10);
65     
66     free(com_ptr);
67     return 0;
68 }

  执行结果如下:

  

  事与愿违,Unisox2虽然有三个算法中最好的压缩率,可是却也拥有最差的压缩和解压性能。

三、总结

  本篇分享了smaz,shoco,unisox2三种短字符串压缩算法,分别探索了它们各自的压缩率与压缩和解压缩性能,结果如下表所示。

表1

  shoco的压缩率最低,但是拥有最高的压缩和解压速率;smaz居中;unisox2拥有最高的压缩率,可是它的压缩和解压性能最低。

  结论与前两章有关长字符串压缩的分析不谋而合:拥有高压缩率,就会损失自身的压缩性能,两者不可兼得。

  实际使用还是看自身需求和环境吧。如果适当压缩就好,那就可以选用shoco,毕竟性能高;想要节约更多的空间,那就选择smaz或者unisox2。

  好了,字符串压缩系列的分享就到此为止了,如果对你有些许帮助,还请各位技术爱好者登录点赞呀,谢谢!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

字符串压缩(三)之短字符串压缩 的相关文章

  • 如何在 Eclipse 中用阿拉伯语读写

    我在 eclipse 中编写了这段代码来获取一些阿拉伯语单词 然后打印它们 public class getString public static void main String args throws Exception PrintS
  • 由于连接超时,无法通过 ImageIO.read(url) 获取图像

    下面的代码似乎总是失败 URL url new URL http userserve ak last fm serve 126 8636005 jpg Image img ImageIO read url System out printl
  • 无法加载 jar 文件的主类

    我使用 Eclipse IDE 开发了一个应用程序 创建应用程序后 我以 jar 格式导出项目 当我尝试运行此 jar 文件时 出现错误 无法加载主类 请帮忙 当您将项目导出为 jar 时 请参阅此所以问题 https stackoverf
  • 如何将 Spotlight for Help 插入本地化的 macOS 应用程序?

    我正在 macOS 上使用 Swing GUI 框架实现 Java 应用程序 当使用system外观和感觉以及screen菜单栏 Swing 自动插入一个搜索栏 called 聚光灯寻求帮助 https developer apple co
  • Java 变量的作用域

    我不明白为什么这段代码的输出是10 package uno public class A int x 10 A int x 12 new B public static void main String args int x 11 new
  • 场景生成器删除 fxml 文件中的导入

    我使用场景构建器 Gluon Scene Builder JavaFX Scene Builder 8 1 1 来创建应用程序的 UI 并使用 Eclipse 开发 JavaFX 现在 每次我在场景生成器中保存某些内容时 它都会从 fxml
  • @EnableTransactionManagement 的范围是什么?

    我试图了解正确的放置位置 EnableTransactionManagement多个 JavaConfig 上下文的情况下的注释 考虑以下场景 我在 JPAConfig java 和 AppConfig java 中有 JPA 配置以及一组
  • Install4j:如何在安装结束时执行命令行 java -jar filename.jar

    在 Intall4j 中 在安装结束时 我只想通过执行如下命令行来初始化某些内容 java jar filename jar 我怎样才能归档这个任务install4j Thanks 将 运行可执行文件或批处理文件 操作添加到 安装屏幕 并设
  • 如何在java中使jpeg无损?

    有没有人可以告诉我如何使用编写 jpeg 文件losslessjava中的压缩 我使用下面的代码读取字节来编辑字节 WritableRaster raster image getRaster DataBufferByte buffer Da
  • 具有多种值类型的 Java 枚举

    基本上我所做的是为国家编写一个枚举 我希望不仅能够像国家一样访问它们 而且还能够访问它们的缩写以及它们是否是原始殖民地 public enum States MASSACHUSETTS Massachusetts MA true MICHI
  • 为什么 ConcurrentHashMap::putIfAbsent 比 ConcurrentHashMap::computeIfAbsent 更快?

    使用 ConcurrentHashMap 我发现computeIfAbsent 比putIfAbsent 慢两倍 这是简单的测试 import java util ArrayList import java util List import
  • 从 html 页面和 javascript 调用 java webservice

    我正在尝试从 javascript 调用 java 实现的 Web 服务 使用 NetBeans IDE 我读过很多关于 jQuery 和 AJAX 的内容 但我似乎无法掌握它 假设我的 Web 服务 WSDL 位于 http localh
  • 从 Java 日历迁移到 Joda 日期时间

    以前 当我第一次设计股票应用相关软件时 我决定使用java util Date表示股票的日期 时间信息 后来我体会到了大部分方法java util Date已弃用 因此 很快 我重构了所有代码以利用java util Calendar 然而
  • 让JScrollPane控制多个组件

    对于我的应用程序 我正在设计一个脚本编辑器 目前我有一个JPanel其中包含另一个JPanel保存行号 位于左侧 以及JTextArea用于允许用户输入代码 位于右侧 目前 我已经实施了JScrollPane on the JTextAre
  • 从 Stax XMLStreamReader 读取以解组部分

    我正在使用 Stax 游标 API 从大型 xml 文件中提取数据 当前 我转到特殊标签的开头并使用 JAXB 解组该标签 这对于格式良好的 xml 文件效果很好 但不久前我有一个文档 其中数十万个标签中有一个未关闭 JAXB 使用 XML
  • 如何在keycloak中动态编辑standalone.xml文件

    我正在尝试通过 docker 编辑standalone xml 并尝试添加 但 keycloak 正在使用它standalone xml 但我可以看到standalone xml 文件中的更改 我需要在standalone xml 文件中添
  • 在 Selenium WebDriver 上如何从 Span 标签获取文本

    在 Selenium Webdriver 上 如何从 span 标记检索文本并打印 我需要提取文本UPS Overnight Free HTML代码如下 div id customSelect 3 class select wrapper
  • 如何移动图像(动画)?

    我正在尝试在 x 轴上移动船 还没有键盘 我如何将运动 动画与boat png而不是任何其他图像 public class Mama extends Applet implements Runnable int width height i
  • struts 教程或示例

    我正在尝试在 Struts 中制作一个登录页面 这个想法是验证用户是否存在等 然后如果有错误 则返回到登录页面 错误显示为红色 典型的登录或任何表单页面验证 我想知道是否有人知道 Struts 中的错误管理教程 我正在专门寻找有关的教程 或
  • 从一个文本文件中获取数据并将其移动到新的文本文件

    我有一个文件 里面有数据 在我的主要方法中 我读入文件并关闭文件 我调用另一种方法 在原始文件的同一文件夹内创建一个新文件 所以现在我有两个文件 原始文件和通过我调用的方法生成的文件 我需要另一种方法 从原始文件中获取数据并将其写入创建的新

随机推荐

  • Linux下的磁盘克隆、磁盘备份、磁盘还原、分区克隆、分区备份、分区还原

    这里主要介绍一个deepin出大杀器软件 深度备份还原工具是深度科技开发的一款备份还原工具 包括磁盘克隆 磁盘备份 磁盘还原 分区克隆 分区备份 分区还原功能 还可以配合深度Live系统进行修复引导 修复分区等操作 其实这个工具的使用场景是
  • 《Programming in Lua 3》读书笔记(十四)

    日期 2014 7 22Programming in Lua 3 的第二部分已经看完了 现在进入第三部分 标准库的阅读Part The Standard Libraries18 The Mathematical Library标准数学库ma
  • 前后端分离实现审核功能

    一 前言 在实际开发中 审核功能是一个非常常用的功能 例如管理后台的文章审核等等 本篇博文将介绍如何基于SpringBoot Vue的前后端分离技术实现审核功能 二 项目准备 本项目使用的技术栈为 前端 Vue ElementUI 后端 S
  • 【Web3 系列开发教程——创建你的第一个 NFT(6)】为 NFT 设置价格

    我想作为 NFT 的创建者 你可能有意将你的 NFT 出售给你的 NFT 爱好者 为此 我们需要为 NFT 定价 一般有两种主要的定价方式 在智能合约内定价 本文所讲 在 NFT 市场或平台上列出你的 NFT 更流行的方法 在智能合约内设置
  • 03-Mybatis增删改查的简单功能实现

    增删改查的实现 在上文中已经建立了mybatis的环境 并且创建了UserMapper xml userMapper 并且完成了一个简单的查询操作 已经可以成功的运行 环境可以正常的跑起来了 下面对整个数据库的基础操作 增删改查的代码进行编
  • elementUI+Vue+json-server做简单的文章后台管理

    elementUI Vue json server做简单的文章后台管理 最近刚接触elementUI不久 为了加深学习理解 便利用elementUI做了个简单练习 在CSDN上写记录一下学习过程 顺便整理回顾一下整个过程 创建项目 vue
  • Android Broadcast注册、发送、接收流程随笔

    Broadcast的注册过程 要动态注册广播 需要调用registerReceiver方法 它在ContextWrapper中实现 会调用mBase registerReceiver方法 mBase具体指向ContextImpl regis
  • java技术总结

    1 js 中正则表达式写法 var 注意不要加引号 加了引号就是一个字符串 不加引号才是正则对象 var new RegExp 此处不可以有 等效于Java写法 2 关于jquery中的 1 是jquery类 的别称 相当于java中的ob
  • 攻防世界web新手-simple_php

    文章目录 XCTF simple php 知识点 源码分析 解题思路 XCTF simple php 题目编号 GFSJ0485 知识点 本题主要考察php的弱类型比较 源码分析
  • 华为鸿蒙系统无缝更新,华为鸿蒙系统已陆续推送! 安卓系统可无缝升级: 升级包容量高达6GB...

    相信大家都知道 自从华为手机业务遭受到芯片断供危机以后 也是直接将会把重点放在软件系统层面 很多花粉们都纷纷期待 华为鸿蒙OS系统早日转正的一天 而华为终端CEO余承东表示 华为鸿蒙OS系统将会在四月份迎来首次推送升级 而华为Mate X2
  • python split(),os.path.split()和os.path.splitext()函数用法

    文章来源 https blog csdn net T1243 3 article details 80170006 coding utf 8 author lei import os os path join 将分离的部分合成一个整体 fi
  • 订单枚举实例

    摘要 订单状态 public enum OrderState 摘要 不限制 All 0 摘要 待付款 UnPaid 1 摘要 已取消 Cancel 2 摘要 待确认 Process 3
  • 【Linux】网络层 — IP协议

    Linux 博客主页 一起去看日落吗 分享博主的在Linux中学习到的知识和遇到的问题 博主的能力有限 出现错误希望大家不吝赐教 分享给大家一句我很喜欢的话 看似不起波澜的日复一日 一定会在某一天让你看见坚持的意义 祝我们都能在鸡零狗碎里找
  • ServerSocket实现超简单HTTP服务器

    1 相关知识简介 HTTP协议 HTTP是常用的应用层协议之一 是面向文本的协议 HTTP报文传输基于TCP协议 TCP协议包含头部与数据部分 而HTTP则是包含在TCP协议的数据部分 如下图 HTTP报文本质上是一个TCP报文 数据部分携
  • librdkafka的安装和使用

    安装 下载https github com edenhill librdkafka 预备环境 The GNU toolchain GNU make pthreads zlib optional for gzip compression su
  • SSL连接的JAVA实现

    SSL连接分为双向认证和单向认证 其中双向认证表示服务器和客户端都需要分别校验对方的身份 单向认证则只需要客户端校验服务器的身份 SSL的双向认证的流程如下图 从以上流程可见 要完成双向认证 服务器端和客户端都需要验证对方的证书 然后再进行
  • Android configChanges属性和configChanges()方法总结

    简介 在Android系统默认的情况下 Configuration改变都会销毁并重建当前Activity 例如当 屏幕方向 或 键盘显示隐藏 变化时 如果不希望重新创建Activity实例 可以在manifest xml文件中可以指定参数a
  • 2019年数学建模美赛经验总结

    北京时间2019年1月29号上午9时 数模美赛结束 美赛结束已经10多天了 我在这次竞赛中负责建模和编程 趁现在记忆还比较清晰 写下这篇博客记录第一次参加数学建模美赛的经历 补更 2019年4月20日公布成绩 笔者最终获得了美赛一等奖 目录
  • 主流加密方式和工具比较

    相关术语 缩写 全称 描述 CryFS CryFS 一种安全的文件加密的工具 Fuse框架 Filesystem In UserSpace 一个实现在用户空间的文件系统框架 loop loop 像块设备一样访问一个文件 dev mapper
  • 字符串压缩(三)之短字符串压缩

    一 通用算法的短字符压缩 开门见山 我们使用一段比较短的文本 Narrator It is raining today So Peppa and George cannot play outside Peppa Daddy it s sto