程序员必知:字符串压缩(三)之短字符串压缩

简介: 程序员必知:字符串压缩(三)之短字符串压缩

  本文来自博客园,作者:T-BARBARIANS,博文严禁转载,转载必究!

前言

  上一篇探索了LZ4的压缩和解压性能,以及对LZ4和ZSTD的压缩、解压性能进行了横向对比。文末的最后也给了一个彩蛋:任意长度的字符串都可以被ZSTD、LZ4之类的压缩算法压缩得很好吗?

  本篇我们就来一探究竟。

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

  开门见山,我们使用一段比较短的文本: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

2 #include [span style="color: rgba(0, 0, 255, 1)">string.h>

3 #include

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

2 #include [span style="color: rgba(0, 0, 255, 1)">string.h>

3 #include

4 #include

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 }//代码效果参考:http://www.ezhiqi.com/bx/art_3591.html

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

2 #include [span style="color: rgba(0, 0, 255, 1)">string.h>

3 #include

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

2 #include [span style="color: rgba(0, 0, 255, 1)">string.h>

3 #include

4 #include

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

<span style="color: rgba(0, 128, 128

相关文章
|
安全 Shell Android开发
Android系统 init.rc开机执行shell脚本
Android系统 init.rc开机执行shell脚本
4842 0
|
小程序 JavaScript
小程序用 rich-text长按复制事件
小程序用 rich-text长按复制事件
944 0
|
6月前
|
人工智能 自然语言处理 运维
2026年OpenClaw(Clawdbot)简单部署指南+新手轻松接入 Slack 教程
在AI自动化工具飞速迭代的2026年,OpenClaw(原Clawdbot、Moltbot)凭借“自然语言指令驱动+全场景任务自动执行”的核心优势,成为新手小白、轻量团队的必备效率工具——它无需专业编程基础,无需手动配置复杂环境,就能轻松实现文件管理、联网搜索、代码生成、团队任务同步等多元化操作。而阿里云推出的OpenClaw一键部署方案,依托云端基础设施的稳定性与自动化能力,预置专属应用镜像、整合所有运行依赖,彻底打破了新手的技术门槛,哪怕你完全不懂服务器、不懂代码,跟着步骤15-20分钟就能完成部署。
748 6
|
2月前
|
人工智能 缓存 API
阿里云百炼TokenPlan价格贵不贵?Credits与Token消耗关系详解+按量计费对比实测
阿里云百炼TokenPlan含标准版(198元/月,2.5万Credits)、高级版(698元/月,10万Credits)、尊享版(1398元/月,25万Credits),单Credit单价低至0.005592元;百万Tokens成本最低1.12元,显著低于按量计费的2元,性价比高。在阿里云百炼官网:https://t.aliyun.com/U/fPVHqY 免费领取千万Tokens
|
开发工具 git 索引
Git使用详细教程(4):git rm使用详解
Git使用详细教程(4):git rm使用详解
730 104
|
人工智能 测试技术 人机交互
深入浅出智能工作流(Agentic Workflow)|技术干货
著名AI学者、斯坦福大学教授吴恩达提出AI Agent的四种设计方式后,Agentic Workflow(智能体工作流)在全球范围内迅速走红,多个行业纷纷实践其应用,并推动了新的Agentic AI探索热潮。吴恩达总结了Agent设计的四种模式:自我反思、工具调用、规划设计及多智能体协作。前两者较普及,后两者则为智能体使用模式从单一大模型向多智能体协同配合完成业务流程的转变奠定了基础。
8785 3
|
Dart
Flutter之ExpansionTile实现以代码方式码折叠、展开
Flutter之ExpansionTile实现以代码方式码折叠、展开
566 4
|
JSON Java Shell
Dockerfile中RUN、CMD、ENTRYPOINT、SHELL命令的区别
理解这些指令的差异和应用场景,有助于构建高效、灵活且易于管理的Docker镜像。在实际应用中,根据需要选择合适的指令,可以有效地控制镜像构建和容器运行的行为。
1073 0
|
运维 网络安全 网络虚拟化
2024网络建设与运维赛题-交换配置教程
SW1, SW2, SW3作为核心交换机,配置了多个VLAN以隔离不同部门的网络,如产品、营销、财务和行政。配置中还包括启用VLAN访问控制,允许特定VLAN通过二层链路,并设置了链路聚合(LACP)以增强SW1和SW2之间的连接可靠性。此外,所有交换机都配置了IP VRF来支持分公司(Branch,RD 1:1)和Internet(RD 2:2)的虚拟专用网络。
2024网络建设与运维赛题-交换配置教程