miniLZO无损压缩库评估

转载自:

http://www.voidcn.com/article/p-snvltjpu-bnz.html

一、应用场合

 

在网络上传输大批量数据的时候,网络传输介质选择好之后网络的传输速度就是固定的了,(如100Mbit的以太网实际测量的传输速度大概在10MByte/秒左右)而要想在固定的时间内传输更多的容量的数据,最常见的解决方案就是在传输之前通过一定的算法把数据的容量压缩小,然后通过网络传输,在对端接收到数据之后,再通过相应的算法进行解压还原。

如果:

    压缩的时间 + 压缩后数据的传输时间 + 解压缩的时间  <    未压缩数据的传输时间

就相当与提高了网络单位时间内的吞吐传输能力,拓宽了网络传输的带宽

二、miniLZO库使用介绍

LZO是一个开源的无损压缩C语言库,其优点是压缩和解压缩比较迅速占用内存小等特点(网络传输希望的是压缩和解压缩速度比较快,压缩率不用很高),其还有许多其他的优点详细参考其网站: http://www.oberhumer.com/opensource/lzo/, 其提供了比较全的LZO库和一个miniLZO库,根据这个情况miniLZO完全满足我们的需求,其提供了1个C文件3个头文件,常用的有4个API在使用的时候包含minilzo.h即可:

  1. 85 /* compression */
  2.  86 LZO_EXTERN(int)
  3.  87 lzo1x_1_compress ( const lzo_bytep src, lzo_uint src_len,
  4.  88 lzo_bytep dst, lzo_uintp dst_len,
  5.  89 lzo_voidp wrkmem );
  6.  90
  7.  91 /* decompression */
  8.  92 LZO_EXTERN(int)
  9.  93 lzo1x_decompress ( const lzo_bytep src, lzo_uint src_len,
  10.  94 lzo_bytep dst, lzo_uintp dst_len,
  11.  95 lzo_voidp wrkmem /* NOT USED */ );
  12.  96
  13.  97 /* safe decompression with overrun testing */
  14.  98 LZO_EXTERN(int)
  15.  99 lzo1x_decompress_safe ( const lzo_bytep src, lzo_uint src_len,
  16. 100 lzo_bytep dst, lzo_uintp dst_len,
  17. 101 lzo_voidp wrkmem /* NOT USED */ );

 

miniLZO库使用也非常方便,在压缩和解压缩之前先调用lzo_init函数进行初始化,如果该函数返回LZO_E_OK就表明没有问题可以继续操作。需要压缩数据调用lzo1x_1_compress函数,需要解压数据就调用lzo1x_decompress函数或lzo1x_decompress_safe函数。这两个函数的区别是lzo1x_decompress_safe函数会对要解压缩数据的有效性进行验证,如果验证通过才会进行解压缩操作而lzo1x_decompress函数则不会这么做,如果数据不是有效的则会产生“段错误”。建议使用lzo1x_decompress_safe函数。一下是这些函数的详细操作说明:

 

  • lzo1x_1_compress函数进行压缩数据操作,其需要5个参数分别是:要压缩的数据、要压缩的数据的大小(单位为字节)、压缩后数据的缓冲区、压缩后缓冲区的大小(值结果参数,调用成功之后存储实际的压缩后的数据大小)、压缩工作缓冲区。压缩数据成功之后会返回LZO_E_OK;
  • lzo1x_decompress和lzo1x_decompress_safe函数进行数据的解压缩操作,其也需要5个参数分别是:要解压缩的数据、要解压缩数据的大小(单位为字节)、解压缩后数据的存放缓冲区、原始数据(未压缩数据)大小(值结果参数,执行成功之后返回解压缩后数据的实际大小)、解压缩不需要工作缓冲区可以为NULL。执行成功返回LZO_E_OK且其第4个参数要和原始数据大小一致。

注意:

  1. lzo1x_1_compress函数的第4个参数是值结果参数,传进去的值是用来指示存放压缩后数据的缓冲区大小,执行成功之后通过指针返回的结果是压缩后的数据实际使用的缓冲区大小,即压缩后的数据大小。压缩后需要的数据的缓冲区的大小上限是可以根据未压缩数据大小进行计算的公式:output_block_size = input_block_size + (input_block_size / 16) + 64 + 3;
  2. lzo1x_1_compress函数的第5个参数是压缩的时候需要使用的工作缓冲区,缓冲的生成在miniLZO库的提供测试例程(testmini.c)中有相关的宏生成该缓冲区,而解压的时候就不需要缓冲区;
  3. lzo1x_decompress_safe解压的时候需要的第4个参数是值结果参数,传进去的值是原始的未压缩数据的大小,执行成功之后通过指针返回的是实际解压缩后的数据的大小。所以压缩之后的数据在传输的时候需要将原始数据的大小和压缩后数据一起传输,否则对方在解压缩的时候将无法解压。可以定义一个数据结构专门用来传输,这些数据在传输的时候相当于有效载荷:

typedef struct{

    unsigned long org_data_size; /* 原始的未压缩数据大小 */

            unsigned char data[MAX_DATA_SIZE]; /* 压缩之后的数据 */

}COMP_DATA, *P_COMP_DATA;

 

三、压缩和解压缩时间的计算

 

在操作(压缩、解压缩)数据之前,获取当前的系统时间,进行相关操作。操作完成之后再次获取系统的时间,对2次获取的时间进行减操作即可得到实际操作所花费的时间。

 

可以通过gettimeofday函数获取当前的系统时间,在2次获取的时间之间进行相减操作即可得到操作所花费的时间,一下的例子是计算的操作所需花费时间的例程:

 

  1. unsigned long interval_ms = 0;    /* 间隔的毫秒数 */
  2. struct timeval stime, etime;
  3.  
  4. gettimeofday(&stime, NULL);
  5.  
  6. /* TODO:Do compression or decompression */
  7.  
  8. gettimeofday(&etime, NULL);
  9.  
  10. interval_ms = (etime.tv_sec - stime.tv_sec) * 1000.0 + (etime.tv_usec - stime.tv_usec)/1000.0

 

四、测试压缩效果

测试的时候使用bmp和文本文件(代码打包之后)做测试,在X86的Linux虚拟机(单核256M内存,Debian 6.0 OS)上测试的效果比较理想一下是测试数据:

  1. 测试文件     原始大小    压缩后大小     压缩率     压缩时间    解压时间
  2. 1.bmp      5292054    159395        3.01%      9.174ms    23.037ms
  3. 2.bmp      6912056    33806  0.489%     8.33ms     36.17ms
  4. 3.bmp      6220856    5101891  82%        25.78ms    28.43ms
  5. lzo.tar      6645760    2457890  36.98%     34.68ms    38.62ms
  6. kdoc.tar     16660480    6987402       41.93%     102.86ms   108.2ms
  7. kinc.tar     18257920    5684927  31.13%     106.87ms   113.86ms

测试了3个复杂程度不同的BMP文件和3个程序代码(lzo.tar是LZO V2.06源代码,kdoc.tar是v2.6.34版本内核的Documentation文件夹打包后,kinc.tar是 v2.6.34版本内核的include文件夹打包 )结果是:

 

  • 文本类型的数据在压缩速度和压缩比率上都比较稳定,解压时间和压缩时间相当;
  • BMP类型的数据的压缩时间和压缩比率和BMP图形的复杂程度相关,而且解压缩花费的时间普遍比压缩花费的时间长;

另外考虑压缩数据需要的内存缓冲区的大小大约为未压缩原始数据的2倍左右(压缩10M的数据需要20M左右的缓冲区,10M保存未压缩数据10M保存压缩后的数据),所以在大数据的时候要适当的考虑将大块的数据分割为小块进行压缩。  minilzo-2.06.zip   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值