我目前使用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