zoukankan      html  css  js  c++  java
  • [编织消息框架][设计协议]优化long,int转换

    理论部分

    一个long占8byte,大多数应用数值不超过int每次传输多4byte会很浪费

    有没有什么办法可以压缩long或int呢?

    答案是有的,原理好简单,如果数值不超过int.max_value的话就"自动变成"int类型

    现在问题又出现了读取时如果知道原来的类型是什么?

    可以先写一个byte是什么类型,再写入值,读时先读一个byte,根据类型做不同解释

    源码解读

     1 public abstract class PacketUtil {
     2  
     3     public final static byte BIT_8 = Byte.MAX_VALUE;
     4     public final static short BIT_16 = Short.MAX_VALUE;
     5     public final static int BIT_32 = Integer.MAX_VALUE;
     6     public final static long BIT_64 = Long.MAX_VALUE;
     7     /***
     8         读取自适应数字
     9     */
    10     public static Number autoReadNum(int offset, byte[] bytes) {
    11         byte bit = bytes[offset];
    12         offset++;
    13         Number ret = null;
    14         switch (bit) {
    15         case 9:    //readLong
    16             ret = readLong(offset, bytes);
    17             break;
    18         case 5: //readInt
    19             ret = readInt(offset, bytes);
    20             break;
    21         case 3: //readShort
    22             ret = readShort(offset, bytes);
    23             break;
    24         case 2:    //readByte
    25             ret = readByte(offset, bytes);
    26             break;
    27         case 1: //zero
    28             ret = (byte) 0;
    29             break;
    30         default:
    31             throw new QSocketException(QCode.SOCKET_UNKNOWN_OPCODE, "auto bytes unknown opcode :" + bit);
    32         }
    33 
    34         return ret;
    35     }
    36     /***
    37         写入自适应数字
    38     */
    39     public static byte autoWriteNum(int offset, Number v, byte[] ret) {
    40         byte bit = getAutoWriteLen(v);
    41         writeByte(offset, bit, ret);
    42         offset++;
    43         switch (bit) {
    44         case 9:    //writeLong
    45             writeLong(offset, v.longValue(), ret);
    46             break;
    47         case 5: //writeInt
    48             writeInt(offset, v.intValue(), ret);
    49             break;
    50         case 3: //writeShort
    51             writeShort(offset, v.shortValue(), ret);
    52             break;
    53         case 2: //writeByte
    54             writeByte(offset, v.byteValue(), ret);
    55             break;
    56         case 1:  //zero
    57             break;
    58         default:
    59             throw new QSocketException(QCode.SOCKET_UNKNOWN_OPCODE, "auto bytes unknown opcode :" + bit);
    60         }
    61         return bit;
    62     }
    63     /***
    64         获取自适合数字大小
    65     */
    66     public static byte getAutoWriteLen(Number value) {
    67         long v = value.longValue();
    68         if (v < 0) {
    69             v = -v;
    70         }
    71         byte bit = 0;
    72         //如果为零返回类型为0
    73         if (v == 0) {
    74             bit = 1;
    75         } else if (v > BIT_32) { //如果超过int max 认为是long类型
    76             bit = 9;
    77         } else if (v > BIT_16) {//如果超过short max 认为是int类型
    78             bit = 5;
    79         } else if (v > BIT_8) { //如果超过byte max 认为是short类型
    80             bit = 3;
    81         } else { //否则为byte类型
    82             bit = 2;
    83         }
    84         return bit;
    85     }
    86 }

    如果数值为0时,可以减小到1byte,少于short.max_value 占3byte,减少60%空间

  • 相关阅读:
    深入了解Java ClassLoader、Bytecode 、ASM、cglib (I)
    如何在ant里import
    敏捷练习(1)评估我的生活方向盘
    你是一个合格的孩子吗?
    [转] C# 路径(目录)
    XML学习记录
    js学习总结不断更新(1)
    LINQ TO XML练习
    做技术,切不可沉湎于技术
    js学习总结持续更新(2)
  • 原文地址:https://www.cnblogs.com/solq111/p/6492229.html
Copyright © 2011-2022 走看看