欢迎访问欧博亚洲(Allbet Game)!

首页科技正文

netty 使用字典提升短文本的压缩效果

admin2020-07-2553

1 问题

  术语:压缩率,compression ratio,压缩后的巨细/压缩前的巨细,越小说明压缩效果越好。

  在使用netty的JdkZlibEncoder举行压缩时,发现了一个问题:它对于短文本(小于2K)的压缩效果很差,压缩率在80%-120%,文本越短,压缩效果越差,甚至可能比没压缩前更大。

  通过研究发现,使用字典可以改善压缩效果。以下详细先容如何做。

2 提取字典

  我们要传输的文本类似于:

  1 <?xml version="1.0" encoding="utf-8" ?>
  2 <Event attribute="TRANSIENT">
  3   <outer id="11" from="1005" to="915880056212" trunk="83057387" callid="24587"/>
  4   <ext id="1005"/>
  5 </Event>

  提取字典的原则:将重复泛起的字符串加入到字典。

  可以提取以下字典:

  1 String[] dictionary = {
  2         "<?xml version=\"1.0\" encoding=\"utf-8\" ?>",
  3         "Event", "TRANSIENT", "attribute", "outer", "from", "trunk",
  4         "callid", "id", "to", "ext"
  5 };
  6 
 

3 测试用例

  使用EmbeddedChannel API来构建测试用例。EmbeddedChannel能够模拟入站和出站的数据流,对于测试ChannelHandler异常有用。

  JdkZlibEncoder的组织函数可以接受一个字典参数:

 

  下面是测试代码:

  1 public class GzipTest {
  2 
  3 
  4     private String xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" +
  5             "<Event attribute=\"TRANSIENT\">" +
  6             "<outer id=\"11\" from=\"1005\" to=\"915880056212\" trunk=\"83057387\" callid=\"24587\"  />" +
  7             "<ext id=\"1005\" />" +
  8             "</Event>";
  9 
 10     private String[] dictionary = {
 11             "<?xml version=\"1.0\" encoding=\"utf-8\" ?>",
 12             "Event", "TRANSIENT", "attribute", "outer", "from", "trunk",
 13             "callid", "id", "to", "ext"
 14     };
 15 
 16 
 17     /**
 18      * 不使用字典压缩
 19      */
 20     @Test
 21     public void test1() {
 22         EmbeddedChannel embeddedChannel = new EmbeddedChannel();
 23         ChannelPipeline pipeline = embeddedChannel.pipeline();
 24         //
 25         pipeline.addLast("gzipDecoder", new JdkZlibDecoder());
 26         pipeline.addLast("gzipEncoder", new JdkZlibEncoder(9));
 27         pipeline.addLast("decoder", new StringDecoder());
 28         pipeline.addLast("encoder", new StringEncoder());
 29         //
 30         System.out.println("*******不使用字典压缩*******");
 31         int compressBefore = xml.getBytes(StandardCharsets.UTF_8).length;
 32         System.out.printf("压缩前巨细:%d \n", compressBefore);
 33         // 模拟输出
 34         embeddedChannel.writeOutbound(xml);
 35         ByteBuf outboundBuf = embeddedChannel.readOutbound();
 36         int compressAfter = outboundBuf.readableBytes();
 37         System.out.printf("压缩后巨细:%d, 压缩率:%d%% \n", compressAfter,
 38                 compressAfter * 100 / compressBefore);
 39 
 40     }
 41 
 42     /**
 43      * 使用字典压缩
 44      */
 45     @Test
 46     public void test2() {
 47         EmbeddedChannel embeddedChannel = new EmbeddedChannel();
 48         ChannelPipeline pipeline = embeddedChannel.pipeline();
 49         // 字典
 50         byte[] dictionaryBytes = String.join("", dictionary)
 51                 .getBytes(StandardCharsets.UTF_8);
 52         //
 53         pipeline.addLast("gzipDecoder", new JdkZlibDecoder(dictionaryBytes));
 54         pipeline.addLast("gzipEncoder", new JdkZlibEncoder(9, dictionaryBytes));
 55         pipeline.addLast("decoder", new StringDecoder());
 56         pipeline.addLast("encoder", new StringEncoder());
 57         //
 58         System.out.println("*******使用字典压缩*******");
 59         int compressBefore = xml.getBytes(StandardCharsets.UTF_8).length;
 60         System.out.printf("压缩前巨细:%d \n", compressBefore);
 61         // 模拟输出
 62         embeddedChannel.writeOutbound(xml);
 63         ByteBuf outboundBuf = embeddedChannel.readOutbound();
 64         int compressAfter = outboundBuf.readableBytes();
 65         System.out.printf("压缩后巨细:%d, 压缩率:%d%% \n", compressAfter,
 66                 compressAfter * 100 / compressBefore);
 67     }
 68 
 69 
 70 }

 

输出:

*******不使用字典压缩*******

压缩前巨细:173

压缩后巨细:150, 压缩率:86%

*******使用字典压缩*******

压缩前巨细:173

压缩后巨细:95, 压缩率:54%

  从输出可以看到,压缩率由86%提升至了54%。

4 进一步

  若是以为手工提取字典效率太低,还可以试一下zstd。zstd是由facebook提供的一个压缩库,它提供了自动提取字典的工具。下令如下:

 zstd --train ./dictionary/* -o ./dict.bin

5 参考资料

zstd github

文本压缩算法的对比和选择

,

ALLBET官网娱乐平台开户

欢迎进入ALLBET官网娱乐平台开户:www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。

转载声明:本站发布文章及版权归原作者所有,转载本站文章请注明文章来源:欧博亚洲(Allbet Game)!

本文链接:https://www.qzkaishanjx.com/post/1035.html

网友评论

最新评论

  • 欧博APP 10/20 说:

    allbet欧博真人客户端欢迎进入allbet欧博真人客户端(Allbet Game):v,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。难怪好多人夸

  • 欧博APP 10/20 说:

    allbet欧博真人客户端欢迎进入allbet欧博真人客户端(Allbet Game):v,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。难怪好多人夸

  • AllbetGmaing开户 10/19 说:

    欧博手机版下载欢迎进入欧博手机版下载(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。可以,在看

  • Allbet官网 10/19 说:

    欧博客户端下载欢迎进入欧博客户端下载(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。此时此刻我在看

  • 欧博开户 10/18 说:

    AllbetGmaing下载欢迎进入AllbetGmaing下载(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。魅力无限啊

  • 欧博开户 10/17 说:

    Allbet Gmaing开户欢迎进入Allbet Gmaing开户(www.aLLbetgame.us):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。关注我好吗

  • 欧博亚洲注册 10/16 说:

    欧博手机版下载欢迎进入欧博手机版下载(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。必备好文之一了~

  • 联博以太坊高度 10/15 说:

    Allbetwww.aLLbetgame.us欢迎进入Allbet平台(Allbet Gaming):www.aLLbetgame.us,欧博平台开放欧博(Allbet)开户、欧博(Allbet)代理开户、欧博(Allbet)电脑客户端、欧博(Allbet)APP下载等业务。没看的都来啊