Java 位数组的高效级联

Java 位数组的高效级联,java,arrays,bitmap,bit,Java,Arrays,Bitmap,Bit,我目前正在编写一段代码,其中我发现两位数组的串联是瓶颈,并就如何提高效率进行了讨论 我的位数组建模如下 public BitArray(int size) { int sizeBytes = size / 8 ; if (size % 8 !=0) sizeBytes++; this.array = new byte[sizeBytes]; this.size = size ; } 其中size是以位为单位的大小 有效连接两个位数组时面临的挑战是,例如,在连

我目前正在编写一段代码,其中我发现两位数组的串联是瓶颈,并就如何提高效率进行了讨论

我的位数组建模如下

public BitArray(int size) { 
    int sizeBytes = size / 8 ;
    if (size % 8 !=0) sizeBytes++;
    this.array = new byte[sizeBytes];
    this.size = size ; 
}
其中size是以位为单位的大小

有效连接两个位数组时面临的挑战是,例如,在连接大小为7的位数组和大小为6的位数组时,需要进行跨接。像这样的 不可能只进行两个阵列拷贝

我正在调查的解决方案,除我目前已实施的解决方案外,还有以下解决方案: 计算“跨接区域”(例如,5位数组的最后3位)。 使用system.array.copy复制第一个数组 使用我的setBit函数手动设置第二个数组中的3个“跨位”。 将第二个数组向左移动3 执行
System.arraycopy()

目前,我手动设置第二个数组的每个位,如下所示

问题是,对于位移位,由于必须对每个字节执行操作,因此该操作实际上相当昂贵,然后必须再次发生跨接

关于如何改进上述技术的想法

以下是性能较差的当前代码:

public static BitArray concatenate(BitArray x1_, BitArray x2_) {
    if (x1_ == null) {
        System.out.println("x1 is null");
        int b = x2_.getArray().length;
        byte[] array = new byte[b];
        System.arraycopy(x2_.getArray(), 0, array, 0, b);
        BitArray res = new BitArray(array);
        res.setSize(x2_.getSize());
        return res;
    } else if (x2_ == null) { 
        System.out.println("x2 is null");
        int b = x1_.getArray().length;
        byte[] array = new byte[b];
        System.arraycopy(x1_.getArray(), 0, array, 0, b);
        BitArray res = new BitArray(array);
        res.setSize(x1_.getSize());
        return res;
    }

    int size1 = x1_.getSize();
    int size2 = x2_.getSize();
    int size = (x1_.getSize() + x2_.getSize()) / 8 ;
    if ((size1 + size2)%8!=0) size++;
    byte[] result = new byte[size];
    System.arraycopy(x1, 0, result, 0, x1.length);
    BitArray res = new BitArray(result);
    res.setSize(size1 + size2);
    for (int i = 0 ; i<size2 ; i++) {
        res.setBit(size1 + i, x2_.getBit(i) );
    }
    return res; 
}
公共静态位数组串联(位数组x1\ux,位数组x2\ux){
如果(x1_==null){
System.out.println(“x1为空”);
int b=x2_ux.getArray().length;
字节[]数组=新字节[b];
System.arraycopy(x2_u.getArray(),0,array,0,b);
BitArray res=新的BitArray(数组);
res.setSize(x2_u.getSize());
返回res;
}如果(x2_==null){
System.out.println(“x2为空”);
int b=x1_u.getArray().length;
字节[]数组=新字节[b];
System.arraycopy(x1_.getArray(),0,array,0,b);
BitArray res=新的BitArray(数组);
res.setSize(x1_.getSize());
返回res;
}
int size1=x1_2;.getSize();
int size2=x2_ux.getSize();
int size=(x1.getSize()+x2.getSize())/8;
如果((size1+size2)%8!=0)size++;
字节[]结果=新字节[大小];
数组复制(x1,0,结果,0,x1.长度);
BitArray res=新的BitArray(结果);
res.setSize(尺寸1+2);

对于(int i=0;i而言,您的代码非常复杂且难以阅读。但是,以下几点可能需要时间:

  • 使用
    %
    运算符
  • 在方法中多次调用
    getSize()
    ——为什么不使用位数组的
    size
    属性
我认为,使用字节/长的链表来表示
位数组
将使连接速度大大加快,因为您可以避免复制任何内容,只需更新指针即可


串联
是一个在数组上执行大量操作的操作吗?如果是的话,我想我会使用一个长链表来表示位数组。您的位数组有多大?

我想您可以在不复制数据的情况下生成一个新数组。类似这样:

class MyBitArray extends BitArray{

    private BitArray a;
    private BitArray b;

    public MyBitArray(BitArray a, BitArray b) throws IllegalArgumentException {
        super(0);
        this.a = a == null ? new BitArray(0) : a;
        this.b = b == null ? new BitArray(0) : b;
    }

    public boolean get(int i){
        if(i < a.length()){
            return a.get(i);
        }
        return b.get(i - a.length());
    }

    public int length(){
        return a.length() + b.length();
    }
}
类MyBitArray扩展了BitArray{
专用比特阵列a;
专用比特阵列b;
公共MyBitArray(位数组a、位数组b)引发IllegalArgumentException{
超级(0);
this.a=a==null?新的位数组(0):a;
this.b=b==null?新的位数组(0):b;
}
公共布尔get(int i){
如果(i
第一个想法:使用long而不是byte,这可能会浪费7个字节,但可能会加快速度。也许您可以通过使用一个“offset”字段来执行“虚拟位移位”,该字段表示数组中数据的起始位置?第二个想法:不要移位,连接字节数组,保留“hole”并在内部使用一些映射。第三个想法:如果内存不是一个问题,那么每一位只使用一个完整的字节。使复制和索引更容易。使用x8破坏内存。您是如何发现这段代码的性能的?为什么您认为这是一个瓶颈?如果它非常关键,请删除System.out.println调用。它们非常昂贵。一个字节/长度不能解决此位移位问题。使用庞大的位数组可能效率更高。您只需更改列表的第一个和最后一个元素。如果您巧妙地实现,则不必移位任何位。