必须有一个更快更好的方法来交换16位字的字节然后这个:
public static void Swap(byte[] data)
{
for (int i = 0; i < data.Length; i += 2)
{
byte b = data[i];
data[i] = data[i + 1];
data[i + 1] = b;
}
}
Run Code Online (Sandbox Code Playgroud)
有没有人有想法?
小智 7
在我申请Uberhacker奖时,我提交以下内容.对于我的测试,我使用了一个8,192字节的Source数组并调用了SwapX2100,000次:
public static unsafe void SwapX2(Byte[] source)
{
fixed (Byte* pSource = &source[0])
{
Byte* bp = pSource;
Byte* bp_stop = bp + source.Length;
while (bp < bp_stop)
{
*(UInt16*)bp = (UInt16)(*bp << 8 | *(bp + 1));
bp += 2;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的基准测试表明此版本比原始问题中提交的代码快1.8倍.
这种方式似乎比原始问题中的方法稍快:
private static byte[] _temp = new byte[0];
public static void Swap(byte[] data)
{
if (data.Length > _temp.Length)
{
_temp = new byte[data.Length];
}
Buffer.BlockCopy(data, 1, _temp, 0, data.Length - 1);
for (int i = 0; i < data.Length; i += 2)
{
_temp[i + 1] = data[i];
}
Buffer.BlockCopy(_temp, 0, data, 0, data.Length);
}
Run Code Online (Sandbox Code Playgroud)
我的基准测试假定重复调用该方法,因此调整_temp数组的大小不是一个因素.此方法依赖于以下事实:一半的字节交换可以通过初始Buffer.BlockCopy(...)调用完成(源位置偏移1).
如果我完全忘记了,请自己测试一下.在我的测试中,这个方法只需要原始方法(我修改为声明byte b循环外部)的大约70%.
我一直很喜欢这个:
public static Int64 SwapByteOrder(Int64 value)
{
var uvalue = (UInt64)value;
UInt64 swapped =
( (0x00000000000000FF) & (uvalue >> 56)
| (0x000000000000FF00) & (uvalue >> 40)
| (0x0000000000FF0000) & (uvalue >> 24)
| (0x00000000FF000000) & (uvalue >> 8)
| (0x000000FF00000000) & (uvalue << 8)
| (0x0000FF0000000000) & (uvalue << 24)
| (0x00FF000000000000) & (uvalue << 40)
| (0xFF00000000000000) & (uvalue << 56));
return (Int64)swapped;
}
Run Code Online (Sandbox Code Playgroud)
我相信你会发现这是最快的方法,并且相当可读和安全。显然这适用于 64 位值,但相同的技术可用于 32 或 16 位。