3

現在、BitConverter を使用して、2 つの unsigned short を signed int 内にパッケージ化しています。このコードは、さまざまな値に対して何百万回も実行されており、コードをさらに最適化できると考えています。私が現在行っていることは次のとおりです。コードは C#/NET であると想定できます。

// to two unsigned shorts from one signed int:
int xy = 343423;
byte[] bytes = BitConverter.GetBytes(xy);
ushort m_X = BitConverter.ToUInt16(bytes, 0);
ushort m_Y = BitConverter.ToUInt16(bytes, 2);

// convet two unsigned shorts to one signed int
byte[] xBytes = BitConverter.GetBytes(m_X);
byte[] yBytes = BitConverter.GetBytes(m_Y);
byte[] bytes = new byte[] {
   xBytes[0],
   xBytes[1],
   yBytes[0],
   yBytes[1],
 };
 return BitConverter.ToInt32(bytes, 0);

そのため、ビットシフトを行うと、配列を構築するオーバーヘッドを回避できることがわかりました。しかし、私の人生では、正しいシフト操作が何であるかを理解できません。私の最初の哀れな試みには、次のコードが含まれていました。

int xy = 343423;
const int mask = 0x00000000;
byte b1, b2, b3, b4;
b1 = (byte)((xy >> 24));
b2 = (byte)((xy >> 16));
b3 = (byte)((xy >> 8) & mask);
b4 = (byte)(xy & mask);
ushort m_X = (ushort)((xy << b4) | (xy << b3));
ushort m_Y = (ushort)((xy << b2) | (xy << b1));

誰かが私を助けることができますか?シフトする前に上位バイトと下位バイトをマスクする必要があると考えています。私が目にするいくつかの例には、type.MaxValue または任意の数 (負の 12 など) を使用した減算が含まれており、かなり混乱しています。

** アップデート **

素晴らしい答えをありがとう。ベンチマーク テストの結果は次のとおりです。

// 34ms for bit shift with 10M operations
// 959ms for BitConverter with 10M operations

static void Main(string[] args)
    {
        Stopwatch stopWatch = new Stopwatch();

        stopWatch.Start();
        for (int i = 0; i < 10000000; i++)
        {
            ushort x = (ushort)i;
            ushort y = (ushort)(i >> 16);
            int result = (y << 16) | x;
        }
        stopWatch.Stop();
        Console.WriteLine((int)stopWatch.Elapsed.TotalMilliseconds + "ms");

        stopWatch.Start();
        for (int i = 0; i < 10000000; i++)
        {
            byte[] bytes = BitConverter.GetBytes(i);
            ushort x = BitConverter.ToUInt16(bytes, 0);
            ushort y = BitConverter.ToUInt16(bytes, 2);

            byte[] xBytes = BitConverter.GetBytes(x);
            byte[] yBytes = BitConverter.GetBytes(y);
            bytes = new byte[] {
                xBytes[0],
                xBytes[1],
                yBytes[0],
                yBytes[1],
            };
            int result = BitConverter.ToInt32(bytes, 0);
        }
        stopWatch.Stop();
        Console.WriteLine((int)stopWatch.Elapsed.TotalMilliseconds + "ms");


        Console.ReadKey();
    }
4

2 に答える 2

5

最も簡単な方法は、2 つのシフトを使用して行うことです。

int xy = -123456;
// Split...
ushort m_X = (ushort) xy;
ushort m_Y = (ushort)(xy>>16);
// Convert back...
int back = (m_Y << 16) | m_X;

ideone のデモ:リンク.

于 2012-09-19T15:06:16.517 に答える
0
int xy = 343423;
ushort low = (ushort)(xy & 0x0000ffff);
ushort high = (ushort)((xy & 0xffff0000) >> 16);
int xxyy = low + (((int)high) << 16);
于 2012-09-19T15:05:37.147 に答える