Algorithm 优化此基于查询的搜索

Algorithm 优化此基于查询的搜索,algorithm,bit-manipulation,Algorithm,Bit Manipulation,我们有两个N位数字0

我们有两个N位数字0
(a[pos]+b[pos]+carry)%2

XOR运算符^执行模2加法,使得可能昂贵的mod运算%不必要。根据语言和编译器的不同,编译器可能会在执行幂为2的mod时为您进行优化。但是,由于您正在进行微观优化,所以这是一个简单的更改,可以消除对在幕后为您进行的优化的依赖

这只是一个简单的建议。正如其他人所建议的那样,使用压缩整数来表示位数组可能也会改进代码的最坏测试。这将是最高有效位的get_c函数,对于所有其他位置,A或B都是1,但不是都是1,需要扫描每个位位置到最低有效位以确定进位。如果对位使用压缩整数,则假定为32位整数,则只需要大约1/32的操作。但是,使用压缩整数要比使用简单的布尔数组复杂一些,而布尔数组很可能只是一个字节数组


在Stackoverflow和net上还有很多其他的例子,可以像使用位数组一样使用INT。

这里有一个解决方案,看起来有点像您的算法。我用字节来演示它,但是当然你可以用32位的字来优化算法,我想你的机器现在有64位的算法

void setbit( unsigned char*x,unsigned int idx,unsigned int bit)
{
   unsigned int digitIndex = idx>>3;
   unsigned int bitIndex = idx & 7;
   if( ((x[digitIndex]>>bitIndex)&1) ^ bit) x[digitIndex]^=(1u<<bitIndex);
}
unsigned int getbit(unsigned char *a,unsigned char *b,unsigned int idx)
{
   unsigned int digitIndex = idx>>3;
   unsigned int bitIndex = idx & 7;
   unsigned int c = a[digitIndex]+b[digitIndex];
   unsigned int bit = (c>>bitIndex) & 1;
   /* a zero bit on the right will absorb a carry, let's check if any */
   if( (c^(c+1))>>bitIndex )
   {
      /* none, we must check if there's a carry propagating from the right digits */
      for(;digitIndex-- > 0;)
      {
         c=a[digitIndex]+b[digitIndex];
         if( c > 255 ) return bit^1; /* yes, a carry */
         if( c < 255 ) return bit;   /* no carry possible, a zero bit will absorb it */
      }
   }
   return bit;
}
如果你发现什么神秘的东西,就问吧。
编辑:哎呀,我颠倒了零位条件…

使用int应该比bools快得多,你确定你正确地实现了它吗?问题的措辞表明提问者可能没有打包int数组。如果他们的原始代码具有N个整数的数组,每个元素为0或1,则他们需要将其更改为N/32个整数的数组,每个元素的范围为0..2^32-1。此外,如果要求他们输入c[i],他们只需从最近a[j]或b[j]已更改为i的最小j处添加。将[pos]+b[pos]+carry%2替换为[pos]^b[pos]^carry如果编译器没有为您进行优化,我不知道为什么,但这里是加速:bool与[pos]+b[pos]+carry%2>bool与[pos]^b[pos]^carry%2>int替换为a[pos]+b[pos]+carry%2如果使用xor,则%2是无用的。使用xor而不是sum-module2不会带来任何加速。使用压缩整数重新编写代码。很快就会回来。
void setbit( unsigned char*x,unsigned int idx,unsigned int bit)
{
   unsigned int digitIndex = idx>>3;
   unsigned int bitIndex = idx & 7;
   if( ((x[digitIndex]>>bitIndex)&1) ^ bit) x[digitIndex]^=(1u<<bitIndex);
}
unsigned int getbit(unsigned char *a,unsigned char *b,unsigned int idx)
{
   unsigned int digitIndex = idx>>3;
   unsigned int bitIndex = idx & 7;
   unsigned int c = a[digitIndex]+b[digitIndex];
   unsigned int bit = (c>>bitIndex) & 1;
   /* a zero bit on the right will absorb a carry, let's check if any */
   if( (c^(c+1))>>bitIndex )
   {
      /* none, we must check if there's a carry propagating from the right digits */
      for(;digitIndex-- > 0;)
      {
         c=a[digitIndex]+b[digitIndex];
         if( c > 255 ) return bit^1; /* yes, a carry */
         if( c < 255 ) return bit;   /* no carry possible, a zero bit will absorb it */
      }
   }
   return bit;
}