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