我目前正在优化一个应用程序,其中一个经常执行的操作是读写二进制。 我需要两种类型的函数:
Set(byte[] target, int index, int value);
int Get(byte[] source, int index);
这些函数需要处理大端和小端的有符号和无符号short、int和long类型。
这里有一些我写的示例,但我需要评估它们的优缺点:
第一种方法是使用Marshal将值写入byte[]内存中,第二种方法是使用普通指针完成,第三种方法使用BitConverter和BlockCopy来实现。
unsafe void Set(byte[] target, int index, int value)
{
fixed (byte* p = &target[0])
{
Marshal.WriteInt32(new IntPtr(p), index, value);
}
}
unsafe void Set(byte[] target, int index, int value)
{
int* p = &value;
for (int i = 0; i < 4; i++)
{
target[offset + i] = *((byte*)p + i);
}
}
void Set(byte[] target, int index, int value)
{
byte[] data = BitConverter.GetBytes(value);
Buffer.BlockCopy(data, 0, target, index, data.Length);
}
以下是读取/获取方法:
第一个方法使用Marshal从byte[]中读取值,第二个方法使用普通指针,第三个方法再次使用BitConverter:
unsafe int Get(byte[] source, int index)
{
fixed (byte* p = &source[0])
{
return Marshal.ReadInt32(new IntPtr(p), index);
}
}
unsafe int Get(byte[] source, int index)
{
fixed (byte* p = &source[0])
{
return *(int*)(p + index);
}
}
unsafe int Get(byte[] source, int index)
{
return BitConverter.ToInt32(source, index);
}
目前我的问题中还未包括边界检查,但需要进行检查...
如果有人能告诉我在这种情况下最好和最快的方法是什么,或者给我一些其他解决方案来处理这个问题,那就太好了。通用解决方案更可取。
我刚做了一些性能测试,以下是结果:
设置 Marshal:45 毫秒,设置指针:48 毫秒,设置 BitConverter:71 毫秒 获取 Marshal:45 毫秒,获取指针:26 毫秒,获取 BitConverter:30 毫秒
看起来使用指针是最快的方式,但我认为 Marshal 和 BitConverter 做了一些内部检查... 有人可以验证一下吗?
Stopwatch
运行并测试一下呢? - Mehrdad Afshari