Bit twiddling:使用按位运算符(<<,|,&等)将字中的字节与零字节交错

时间:2012-12-11 04:42:29

标签: java performance assembly bit-manipulation

给定long字节WXYZ(其中每个字母都是一个字节),我想要一些快速位错误的代码,它将创建两个longs,其字节与原始字节相同,但与0字节交错。

例如,假设long的值为ABCDEFGH(每个字母为一个字节),则产生两个长数:

0A0B0C0D
0E0F0G0H

相当于:但速度快的东西:

long result1 = expand((int)(input >>> 32));
long result2 = expand((int)input);

long expand(int inputInt) {
  long input = intputInt;
  return
    (input & 0x000000FF)       | 
    (input & 0x0000FF00) <<  8 | 
    (input & 0x00FF0000) << 16 | 
    (input & 0xFF000000) << 24;
}

3 个答案:

答案 0 :(得分:3)

以下对我来说快了约25%(Java 7,使用Google Caliper进行基准测试),YMMV可能因编程而异:

long a = (input | (input << 16));
long result = (a & 0xFF000000FFL) + ((a & 0xFF000000FF00L) <<8);

这个想法是使用一些额外的并行性与原始方法。

第一行是一个巧妙的技巧,可以在第17-32位产生垃圾,但是你并不在乎,因为你无论如何都会掩盖它。 : - )

答案 1 :(得分:0)

long expand(int inputInt) {
  long input = intputInt;
  return
    (input & 0x000000FF) <<  8 | 
    (input & 0x0000FF00) << 16 | 
    (input & 0x00FF0000) << 24 | 
    (input & 0xFF000000) << 32;
}

答案 2 :(得分:0)

在C ++中,您可以尝试使用union:

typedef union
{
    char bytes[8];
    long value;
} PlatformSpecificSolution;

long expand(int valueInt)
{
    PlatformSpecificSolution pss;
    pss.value = valueInt;
    pss.bytes[6] = pss.bytes[3]; pss.bytes[3] = 0;
    pss.bytes[4] = pss.bytes[2]; pss.bytes[2] = 0;
    pss.bytes[2] = pss.bytes[1]; pss.bytes[1] = 0;
    // pss.bytes[0] = pss.bytes[0];
    return pss.value;
 }

我不知道这是否更快(您必须在要支持的平台上运行基准测试)。这种解决方案肯定更容易出错。你应该总是问问自己,性能优势是否会带来不易维护的代码的缺点。