Java - 将写入值优化为位到bytebuffer的位

Ela*_*ian 10 java networking byte bytebuffer bit

我目前正在研究一些网络代码(这是我的第一个服务器)并且有一个关于优化特定函数的快速问题,该函数将值写为位然后将它们打包成一个字节.优化此功能的原因是因为每个服务器标记使用数千次来将数据打包发送到多个客户端.

示例可以更好地用于解释函数试图完成的内容:值3可以由两位表示.在二进制中,它看起来像00000011.该函数会将此二进制值转换为11000000.当再次调用该函数时,它将知道从第3个最高有效位(右边的第3个/第13个)开始,并在当前字节中最多写入6位.如果那时剩下的位要写,它将从一个新字节开始.

这样做的目的是节省空间,如果有多个值可以小于byte.

我目前的功能如下:

 private ByteBuffer out = ByteBuffer.allocate(1024);
 private int bitIndex = 0;
 /*
  * Value: The value to write
  * Amount: The number of bits to represent the value in.
  */
     public OutputBuffer writeBits(long value, int amount) {
    if (bitIndex != 0) {
        int remainingBits = 8 - bitIndex;
        int bytePos = out.position() - 1;
        byte current = out.get(bytePos);
        int shiftAmount = amount - remainingBits;
        int bitsWritten = amount < remainingBits ? amount : remainingBits;
        int clearShiftAmount = 8 - bitsWritten + 56;

        byte b;
        if (shiftAmount < 0) {
            b = (byte) (current | (value << remainingBits - amount));
        } else {
            //deal with negative values
            long temp = (value >> shiftAmount);
            temp =  (temp << clearShiftAmount);
            temp = (byte) (temp >>> clearShiftAmount);
            b = (byte) (current | temp);
        }
        out.put(bytePos,b);
        bitIndex = (bitIndex + bitsWritten) % 8;
        amount -= bitsWritten;
    }
    if (amount <= 0) {
        return this;
    }
    bitIndex = amount & 7;
    int newAmount = amount - bitIndex;
    //newValue should not equal 2047
    for (int i = 0; i != newAmount; i += 8) {
        writeByte((byte) ((value >> i)), false);
    }
    if (bitIndex > 0)
        writeByte((byte) (value << (8 - bitIndex)), false);
    return this;
}
Run Code Online (Sandbox Code Playgroud)

由于我是新手,我认为可能有更有效的方法,可能使用位屏蔽或某种查找表?任何想法或朝着正确方向转向都会很棒.干杯.

Rus*_*son 5

好的,我调整了原始算法以删除一些冗余数学,并且我削减了大约10%的折扣(在我的机器上从0.016毫秒变为大约0.014毫秒).我还改变了我的测试以运行每个算法1000次.

在最后一个for循环中似乎也有一些节省,因为相同的位被反复移位.如果你能以某种方式保留可能有帮助的前一班次的结果.但这会改变字节输出的顺序,因此需要更多思考.

public void writeBits3(long value, int amount) {
    if (bitIndex != 0) {
        int remainingBits = 8 - bitIndex;
        int bytePos = out.position() - 1;
        byte current = out.get(bytePos);
        int shiftAmount = amount - remainingBits;

        int bitsWritten = 0;
        if (shiftAmount < 0) {
            bitsWritten = amount;
            out.put(bytePos, (byte) (current | (value << -shiftAmount)));
        } else {
            bitsWritten = remainingBits;
            out.put(bytePos, (byte) (current | (value >> shiftAmount)));
        }

        bitIndex += bitsWritten;
        amount -= bitsWritten;
        if (bitIndex >= 8) {
            bitIndex = 0;
        }
    }
    if (amount <= 0) {
        return;
    }
    bitIndex = amount & 7;
    int newAmount = amount - bitIndex;
    long newValue = (value >> bitIndex);
    for (; newAmount >= 8; newAmount -= 8) {
        out.put((byte) (newValue >> newAmount));
    }
    out.put((byte) (value << (8 - bitIndex)));
}
Run Code Online (Sandbox Code Playgroud)