下面的函数需要两个BitSets
,复制第一个(它不能被覆盖),将副本与第二个(按位AND)相交并返回结果的基数。
public int getIntersectionSize(BitSet bits1, BitSet bits2) {
BitSet copy = (BitSet) bits1.clone();
copy.and(bits2);
return copy.cardinality();
}
我对这段代码加速感兴趣吗?这个功能被称为十亿次,所以即使是微秒加速也是有道理的,而且我对最快的代码感到好奇。
答案 0 :(得分:2)
如果您要多次使用每个BitSet
,那么创建与每个long
对应的BitSet
数组可能是值得的。对于每个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;
}
答案 1 :(得分:1)
这是一个替代版本,但我不确定它是否真的更快,取决于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;
}
答案 2 :(得分:0)
最近我一直在寻找解决方案,这是我想出的:
services.AddTransient<IRepository, Repository>()
也许有人想花点时间在这里比较不同的解决方案并发布结果...