1

longwith バイト(各文字は 1 バイト) が与えられた場合、元のバイトと同じバイトをWXYZ2 つ作成し、0 バイトをインターリーブする高速なビット調整コードが必要です。longs

たとえば、longwith 値ABCDEFGH(各文字は 1 バイト) を指定すると、2 つの long 型が生成されます。

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;
}
4

3 に答える 3

3

以下は私にとって約 25% 高速です (Java 7、Google Caliper を使用してベンチマーク)。もちろん、YMMV はコンパイラによって異なる場合があります。

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

アイデアは、元のアプローチに対して少し追加の並列処理を使用することです。

最初の行は、ビット 17 から 32 でガベージを生成する巧妙なトリックですが、とにかくそれをマスクするつもりなので気にしません。:-)

于 2012-12-11T06:36:37.887 に答える
0
long expand(int inputInt) {
  long input = intputInt;
  return
    (input & 0x000000FF) <<  8 | 
    (input & 0x0000FF00) << 16 | 
    (input & 0x00FF0000) << 24 | 
    (input & 0xFF000000) << 32;
}
于 2012-12-11T05:51:26.057 に答える
0

C++ では、共用体を使用することができます。

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;
 }

これが速いかどうかはわかりません (サポートしたいプラットフォームでベンチマークを実行する必要があります)。このソリューションは間違いなくエラーが発生しやすいです。パフォーマンス上の利点が保守性の低いコードの欠点を上回っているかどうか、常に自問する必要があります。

于 2012-12-11T06:22:19.280 に答える