【发布时间】:2011-01-03 10:47:50
【问题描述】:
我目前正在优化一个应用程序,其中一项经常进行的操作是读取和写入二进制文件。我需要两种功能:
Set(byte[] target, int index, int value);
int Get(byte[] source, int index);
这些函数是有符号和无符号短、整数和长字节序的大字节序和小字节序所需要的。
以下是我制作的一些示例,但我需要评估一下优缺点:
第一种方法是使用 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);
}
需要进行边界检查,但还不是我的问题的一部分...
如果有人能告诉我在这种情况下什么是最好和最快的方法,或者给我一些其他解决方案,我会很高兴。一个通用的解决方案会更好
我刚刚做了一些性能测试,结果如下:
设置元帅:45 毫秒,设置指针:48 毫秒,设置 BitConverter:71 毫秒 获取 Marshal:45 毫秒,获取指针:26 毫秒,获取 BitConverter:30 毫秒
似乎使用指针是快速的方法,但我认为 Marshal 和 BitConverter 会进行一些内部检查...有人可以验证吗?
【问题讨论】:
-
你有代码,为什么不运行它并使用
Stopwatch进行测试? -
:/ :\ 你说得对,我会这样做是为了快速编辑我的问题,但这不是我帖子的唯一要点。我正在寻找替代品,也许还有通用的方法
-
对这个问题提出了质疑:只有 I/O 才需要转换为二进制文件。 I/O 操作本身总是比处理位慢几个数量级。最好的优化只能为您带来百分之几的改进。