在Java中,将位打包到字节[]并将其读回的最有效方法是什么?

在Java中,将位打包到字节[]并将其读回的最有效方法是什么?,java,bit-manipulation,bit,packing,Java,Bit Manipulation,Bit,Packing,我目前使用这两个函数在字节数组中打包和读取位。想知道是否有人有更好的想法或更快的方法来做这件事 编辑了程序,进行了一些优化,并编制了一些计算表格。目前,100mil的输入和获取大约需要12秒,而不是现在的16秒 如果有人在使用当前代码,请确保传递给Put的值是正数,因为它期望无符号数下降。如果有兴趣,我可以把签署和未签署的版本 class BitData { static void Put(byte Data[], final int BitOffset, int NumBits, fi

我目前使用这两个函数在字节数组中打包和读取位。想知道是否有人有更好的想法或更快的方法来做这件事

编辑了程序,进行了一些优化,并编制了一些计算表格。目前,100mil的输入和获取大约需要12秒,而不是现在的16秒

如果有人在使用当前代码,请确保传递给Put的值是正数,因为它期望无符号数下降。如果有兴趣,我可以把签署和未签署的版本

class BitData
{
    static void Put(byte Data[], final int BitOffset, int NumBits, final int Value)
    {
        final long valLong=(Value&((1L<<NumBits)-1L));
        int posByte=BitOffset>>3;
        int posBit=BitOffset&7;
        int valByte;
        int ModifyBits;

        long lValue;
        int LeftShift;
        ModifyBits=8-posBit;
        if(NumBits<ModifyBits) ModifyBits=NumBits;
        LeftShift=(8-posBit-ModifyBits);
        while(true)
        {
            valByte = Data[posByte];
            if(ModifyBits==8)
            {
                lValue=valLong<<(32-NumBits)>>(24);
                Data[posByte]=(byte)lValue;
            }
            else
            {   
                lValue=valLong<<(32-NumBits)>>(32-ModifyBits)<<LeftShift;
                Data[posByte]=(byte)((valByte & ~(((1<<ModifyBits)-1) << LeftShift)) | lValue);
            }
            NumBits-=ModifyBits;
            if(NumBits==0) break;
            posByte++;          
            ModifyBits=8;
            if(NumBits<ModifyBits) 
            {
                ModifyBits=NumBits;
                LeftShift=(8-ModifyBits);
            }
        }
    }

    static int GetInt(byte Data[], final int BitOffset, int NumBits)
    {       
        int posByte=BitOffset>>3;
        int posBit=BitOffset&7;


        long Value=0;
        int ModifyBits;
        int valByte;
        int LeftShift;
        ModifyBits=8-posBit;
        if(NumBits<ModifyBits) ModifyBits=NumBits;
        LeftShift=(8-posBit-ModifyBits);
        while(true)
        {
            valByte = Data[posByte] & 0xff;
            if(ModifyBits==8) Value+=valByte;
            else Value+=(valByte & ((1<<ModifyBits)-1) << LeftShift) >> LeftShift;              
            NumBits-=ModifyBits;
            if(NumBits==0) break;
            posByte++;
            ModifyBits=8;
            if(NumBits<ModifyBits) 
            {
                ModifyBits=NumBits;
                LeftShift=(8-ModifyBits);
            }
            Value<<=ModifyBits;

        }
        return (int)Value;
    }
}
类位数据
{
静态void Put(字节数据[],最终整数位偏移量,整数位数,最终整数值)
{
最终长valLong=(值和((1L3);
int posBit=位偏移量&7;
int值字节;
int-ModifyBits;
长左值;
int左移位;
ModifyBits=8位;

如果(NumBits一个完全不同的方法是定义所有可能组合的静态表,并执行查找,而不是每次都计算结果。我认为这就是加密中的方法。数组[I]X3应该比它的按位操作快得多。但是它会占用一些堆。

你考虑过使用内置的
java.util.BitSet
?是的,我先尝试过。它比这种方法慢得多。它是一个服务器,每秒需要打包和解包数百万个数据包,所以需要最快的方法它。我已经用这两个函数做了尽可能多的优化。只是好奇在Java中是否有我没有想到的完全不同的路径。是的。用C编写并使用JNI将其连接到Java。该程序还需要可移植性。我不熟悉JNI。你能告诉我该程序是否仍然可以在不同的操作系统服务器上运行吗如果我走那条路?@JimGarrison-你有没有任何基准测试来证明这么小的计算的加速比会超过进行JNI方法调用的开销?(对OP来说-我认为这是个糟糕的建议。)我将尝试列出一些部分,看看是否有速度提高。我添加的两个表似乎将性能提高了约7-10%。在代码中找不到其他适合该表的内容。10%的增益仍然不错。