Java - 优化将值作为位写入字节缓冲区

标签 java networking byte bit bytebuffer

我目前正在编写一些网络代码(这是我的第一台服务器),并且有一个关于优化特定函数的快速问题,该函数将值写入位,然后将它们打包成一个字节。优化这个函数的原因是因为它在每个服务器滴答中被使用数千次来打包要发送给多个客户端的数据。

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

这样做的目的是在您有多个小于字节的值时节省空间。

我当前的函数如下所示:

 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;
}

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

最佳答案

好的,我调整了您的原始算法以删除一些冗余数学,并且减少了大约 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)));
}

关于Java - 优化将值作为位写入字节缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48762114/

相关文章:

java - Spring中HTTP请求后是否需要清除MDC

java - Android逆向后如何读取混淆后的Java代码

java - 告诉 java 接受自签名证书(在某种程度上是重复的问题)

node.js - Node Web 服务器外部不可见,但 Python 可见(MacOS)

c - 使用 libnet 发送 ARP 请求,但 arp 缓存在获得 ARP 回复后不会更新

java - 未获取位置时关闭应用程序的对话框

c++ - 调用 accept() 导致 WSAEFAULT 10014 Bad address

java - byte[] byteArray = anotherByteArray 的作用是什么?

compression - 如何以字节表示 LZW 输出?

c - C中的位重排/操作