我目前使用BitConverter在signed int中打包兩個unsigned short。此代碼針對不同的值執行數百萬次,我認爲代碼可以進一步優化。這是我目前正在做的 - 你可以假設代碼是C#/ NET。將signed int轉換爲兩個unsigned short用於重構
// 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);
因此,我發現我可以避免構造數組的開銷,如果我bitshift。但是對於我的生活,我無法弄清楚正確的換擋操作是什麼。我的第一次可憐的嘗試涉及以下代碼:
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));
有人可以幫我嗎?我想我需要在移位之前屏蔽高位和低位字節。我看到的一些例子包括帶有類型.MaxValue的減法或任意數字,例如負十二,這相當混亂。
**更新**
謝謝你的好的答案。這裏有一個基準測試的結果:
// 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();
}
比我的小。 +1 – spender
在這種情況下,對'uint'的強制轉換不是必需的,因爲當您投射到'ushort'時,您將放棄符號擴展位。 – LukeH
@LukeH你是對的,我編輯了答案,放棄了不必要的演員。 – dasblinkenlight