当前位置:   article > 正文

zstd压缩与lz4压缩比较_zstd和lz4哪个好

zstd和lz4哪个好

最近由于业务需求需要对数据进行压缩,相关压缩算法介绍的都比较多,比较详细,笔者在这里就不赘述。本篇主要针对C语言调用zstd、lz4压缩算法的接口调用,并对其做简单的比较。下述案例中的源码也可通过该链接下载 : 压缩算法包

ZSTD源码编译及测试

源码编译

        1、获取zstd源码,网址:https://github.com/facebook/zstd/,打开网址如下操作:

点击红色获取Releases版本源码,拉到页面最下边如下图:

        2、将源码移到自己的环境解压(tar -zxcf zstd-1.5.2.tar.gz)、编译(make),生成zstd静态库、动态库及程序调用所需头文件。如下图所示:

 案例调用

        1、创建一个与刚解压的zstd-1.5.2目录同级的目录zstd_demo;将案例代码与Makefile文件放入目录中,如下图所示:

         2、zstd_demo.c与Makefile文件如下:

  1. /********************************************
  2. Date : 2022-05-17
  3. Author : lijd
  4. Func : 用生产业务数据测试zstd压缩算法
  5. ********************************************/
  6. #include <stdio.h>
  7. #include <sys/time.h>
  8. #include "zstd.h"
  9. #include <string.h>
  10. char g_str[] ="2323024C5A474E41374535334C583636363032330101006016050D121015020013FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0006D1F4A901D0C74FFFFFFFFF880002001CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88F001000C0100000006D1F4A901D0C74FA12323034C5A474E41374535334C583636363032330101006016050C0B012E020006FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0006D1F4B001D0C8EFFFFFFFFF880002001CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88F001000C0100000006D1F4B001D0C8EF872323034C5A474E41374535334C583636363032330101006016050C0B012F020007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0006D1F4B701D0C8E7FFFFFFFF880002001CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88F001000C0100000006D1F4B701D0C8E7872323034C5A474E41374535334C583636363032330101006016050C0B0130020008FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0006D1F4B701D0C8E0FFFFFFFF880002001CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88F001000C0100000006D1F4B701D0C8E0972323024C5A474E41374535334C583636363032330101006016050D121017020014FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0006D1F4A901D0C74FFFFFFFFF880002001CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88F001000C0100000006D1F4A901D0C74FA42323034C5A474E41374535334C583636363032330101006016050C0B0131020009FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0006D1F4B701D0C8DDFFFFFFFF880002001CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88F001000C0100000006D1F4B701D0C8DD972323024C5A474E41374535334C583636363032330101006016050D121018020015FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0006D1F4A901D0C74FFFFFFFFF880002001CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88F001000C0100000006D1F4A901D0C74FAA2323034C5A474E41374535334C583636363032330101006016050C0B013202000AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0006D1F4B501D0C8D6FFFFFFFF880002001CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88F001000C0100000006D1F4B501D0C8D6972323034C5A474E41374535334C583636363032330101006016050C0B013302000BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0006D1F4B001D0C8CEFFFFFFFF880002001CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88F001000C0100000006D1F4B001D0C8CE97";
  11. // 十六进制转字符串
  12. int HexToStr(char *p_hexstr, int iHexLen, char *pdststr)
  13. {
  14. int iret = 0;
  15. while(p_hexstr != NULL && pdststr != NULL && iHexLen > 1)
  16. {
  17. char cTemp = '0';
  18. // printf("1:%c, 2:%c\n", p_hexstr[0], p_hexstr[1]);
  19. // 小写统一转大写
  20. if(p_hexstr[0] >= '0' && p_hexstr[0] <= '9')
  21. {
  22. cTemp = p_hexstr[0] - '0';
  23. }
  24. else if(p_hexstr[0] >= 'A' && p_hexstr[0] <= 'F')
  25. {
  26. cTemp = p_hexstr[0] - 'A' + 10;
  27. }
  28. else if(p_hexstr[0] >= 'a' && p_hexstr[0] <= 'f')
  29. {
  30. cTemp = p_hexstr[0] - 'a' + 10;
  31. }
  32. else
  33. {
  34. printf("the hex str is error!\n");
  35. break;
  36. }
  37. *pdststr = cTemp * 16;
  38. if(p_hexstr[1] >= '0' && p_hexstr[1] <= '9')
  39. {
  40. cTemp = p_hexstr[1] - '0';
  41. }
  42. else if(p_hexstr[1] >= 'A' && p_hexstr[1] <= 'F')
  43. {
  44. cTemp = p_hexstr[1] - 'A' + 10;
  45. }
  46. else if(p_hexstr[1] >= 'a' && p_hexstr[1] <= 'f')
  47. {
  48. cTemp = p_hexstr[1] - 'a' + 10;
  49. }
  50. else
  51. {
  52. printf("the hex str is error!\n");
  53. break;
  54. }
  55. *pdststr += cTemp;
  56. // printf("---iHexLen:%d, pdststr:%c\n", iHexLen, *pdststr);
  57. iHexLen -= 2;
  58. p_hexstr += 2;
  59. pdststr++;
  60. iret++;
  61. }
  62. // printf("iret : %d\n", iret);
  63. return iret;
  64. }
  65. // 字符串转十六进制
  66. int StrToHex(const char *p_strstr, int iStrLen, char *pdststr)
  67. {
  68. int index_str = 0, index_hex = 0;
  69. const char cHex[] = "0123456789ABCDEF";
  70. while(index_str < iStrLen && p_strstr != NULL && pdststr != NULL)
  71. {
  72. pdststr[index_hex++] = cHex[((UCHAR)p_strstr[index_str])/16];
  73. pdststr[index_hex++] = cHex[((UCHAR)p_strstr[index_str++])%16];
  74. }
  75. return index_hex;
  76. }
  77. int main()
  78. {
  79. struct timeval curTime;
  80. char src[2048] = {0};
  81. char dst[2048] = {0}, src2[2048] = {0};
  82. int iStrlen = HexToStr(g_str, strlen(g_str), src);
  83. printf("业务数据原始长度 : %d 字节\n", iStrlen);
  84. gettimeofday(&curTime, NULL);
  85. int time_usec = curTime.tv_usec;
  86. int cSize = ZSTD_compress(dst, 2048, src, iStrlen, 3);
  87. gettimeofday(&curTime, NULL);
  88. time_usec = curTime.tv_usec - time_usec;
  89. printf("ZSTD 压缩所用时间 : %u 微秒, 压缩后长度 : %d 字节\n", time_usec, cSize);
  90. gettimeofday(&curTime, NULL);
  91. time_usec = curTime.tv_usec;
  92. int cSize2 = ZSTD_decompress(src2, 2048, dst, cSize);
  93. gettimeofday(&curTime, NULL);
  94. time_usec = curTime.tv_usec - time_usec;
  95. printf("压缩后数据解压所需时间 : %u 微秒, 解压后数据长度 : %d 字节\n", time_usec, cSize2);
  96. return 0;
  97. }
  1. # Func: zstd_demo
  2. # Auth: lijd
  3. # Date: 2022/05/17
  4. CC := gcc
  5. TARGET := zstd_demo
  6. INCLUDES := ../zstd-1.5.2/lib/
  7. LIBDIRS := ../zstd-1.5.2/lib/
  8. LIBS := zstd
  9. FLAGES := $(addprefix -I, $(INCLUDES)) $(addprefix -L, $(LIBDIRS)) $(addprefix -l, $(LIBS))
  10. SRCS := $(wildcard *.c)
  11. $(TARGET): $(SRCS)
  12. $(CC) -g -Wall -o $@ $^ $(FLAGES)
  13. @echo "==================================== Build OK!!! ===================================="
  14. .PHONY: clean
  15. clean:
  16. @rm -rf $(TARGET)

        3、编译成功后,运行可能找不到依赖的动态库,需要将环境变量设置一下,注意笔者用的这种设置方式只是暂时的。如下图:

 lz4源码编译及测试     

  源码编译

         1、获取zstd源码,网址:Index of /ubuntu/pool/main/l/lz4,打开网址如下操作:

          2、将源码移到自己的环境解压(tar -zxcf lz4_1.9.2.orig.tar.gz)、编译(make),生成lz4静态库、动态库及程序调用所需头文件。如下图所示:

案例调用

        1、创建一个与刚解压的lz4_1.9.2目录同级的目录lz4_demo;将test.c与Makefile文件放入目录中,代码只有调用压缩解压的函数接口有变动,其余都一样,Makefile只有小的改动。这里只给出变动的main函数如下:

  1. int main()
  2. {
  3. struct timeval curTime;
  4. char src[2048] = {0};
  5. char dst[2048] = {0}, src2[2048] = {0};
  6. int iStrlen = HexToStr(g_str, strlen(g_str), src);
  7. printf("业务数据原始长度 : %d 字节\n", iStrlen);
  8. gettimeofday(&curTime, NULL);
  9. int time_usec = curTime.tv_usec;
  10. int cSize = LZ4_compress_default(src, dst, iStrlen, 2048);
  11. gettimeofday(&curTime, NULL);
  12. time_usec = curTime.tv_usec - time_usec;
  13. printf("LZ4 压缩所用时间 : %u 微秒, 压缩后长度 : %d 字节\n", time_usec, cSize);
  14. gettimeofday(&curTime, NULL);
  15. time_usec = curTime.tv_usec;
  16. int cSize2 = LZ4_decompress_safe(dst, src2, cSize, 2048);
  17. gettimeofday(&curTime, NULL);
  18. time_usec = curTime.tv_usec - time_usec;
  19. printf("压缩后数据解压所需时间 : %u 微秒, 解压后数据长度 : %d 字节\n", time_usec, cSize2);
  20. return 0;
  21. }

        2、编译成功后运行如下图:

 总结

        笔者将相同的业务数据,用不同的压缩解压算法进行压缩、解压;得到的结构也显而易见:zstd(81%)在压缩率优于lz4(71%);但在压缩、解压时间上lz4远远优于zstd,lz4不愧为压缩界的速度之王

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/码创造者/article/detail/834552
推荐阅读
相关标签
  

闽ICP备14008679号