[英]What would be the fastest way to intersect two bitsets into a new BitSet in Java?
[英]Java fastest way to get cardinality of BitSet intersection
下面的函數需要兩個BitSets
,復制第一個(它不能被覆蓋),將副本與第二個(按位AND)相交並返回結果的基數。
public int getIntersectionSize(BitSet bits1, BitSet bits2) {
BitSet copy = (BitSet) bits1.clone();
copy.and(bits2);
return copy.cardinality();
}
我對這段代碼加速感興趣嗎? 這個功能被稱為十億次,所以即使是微秒加速也是有道理的,而且我對最快的代碼感到好奇。
如果您要多次使用每個BitSet
,那么創建一個對應於每個BitSet
的long
數組可能是值得的。 對於每個BitSet
:
long[] longs = bitset.toLongArray();
然后,您可以使用以下方法,這可以避免創建克隆BitSet
的開銷。 (這假設兩個數組的長度相同)。
int getIntersectionSize(long[] bits1, long[] bits2) {
int nBits = 0;
for (int i=0; i<bits1.length; i++)
nBits += Long.bitCount(bits1[i] & bits2[i]);
return nBits;
}
這是一個替代版本,但我不確定它是否真的更快,取決於nextSetBit
。
public int getIntersectionsSize(BitSet bits1, BitSet bits2) {
int count = 0;
int i = bits1.nextSetBit(0);
int j = bits2.nextSetBit(0);
while (i >= 0 && j >= 0) {
if (i < j) {
i = bits1.nextSetBit(i + 1);
} else if (i > j) {
j = bits2.nextSetBit(j + 1);
} else {
count++;
i = bits1.nextSetBit(i + 1);
j = bits2.nextSetBit(j + 1);
}
}
return count;
}
以上是可讀版本,希望編譯器足夠好,但你可以手動優化它我猜:
public int getIntersectionsSize(BitSet bits1, BitSet bits2) {
int count = 0;
for (int i = bits1.nextSetBit(0), j = bits2.nextSetBit(0); i >= 0 && j >= 0; ) {
while (i < j) {
i = bits1.nextSetBit(i + 1);
if (i < 0)
return count;
}
if (i == j) {
count++;
i = bits1.nextSetBit(i + 1);
}
while (j < i) {
j = bits2.nextSetBit(j + 1);
if (j < 0)
return count;
}
if (i == j) {
count++;
j = bits2.nextSetBit(j + 1);
}
}
return count;
}
我最近一直在尋找解決方案,這就是我想出來的:
int intersectionCardinality(final BitSet lhs, final BitSet rhs) {
int lhsNext;
int retVal = 0;
int rhsNext = 0;
while ((lhsNext = lhs.nextSetBit(rhsNext)) != -1 &&
(rhsNext = rhs.nextSetBit(lhsNext)) != -1) {
if (rhsNext == lhsNext) {
retVal++;
rhsNext++;
}
}
return retVal;
}
也許有人想花時間在這里比較不同的解決方案並發布結果......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.