[英]How to optimize this further (speed first, then memory)
我有这个小的代码,需要一个对象并将其转换为byte []。 使用C#4.0。 我可以进一步优化速度和内存使用吗? 即使很小的变化也将是巨大的-每秒调用数千次以上。
public static byte[] ObjectToByteArray(object obj)
{
if (obj == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
using (ms)
{
bf.Serialize(ms, obj);
}
return ms.ToArray();
}
如果您想进一步优化它,那么您首先需要知道的是您目前在哪里花费最多的时间。 您是否通过探查器运行此程序? 结果如何?
我还会问自己“优化此功能将为用户带来什么具体好处?”。 换句话说,我是否在优化它,是因为作为一名工程师,我想完善代码,还是因为它将为交付解决方案的人员带来真正的好处?
我怀疑您花了大部分时间执行实际的序列化,更改为其他序列化器可能会产生最大的收益。 有关替代的,更快的序列化器,请参见以下问题:
问题在于BinaryFormatter使用反射来读取对象的字段。 假设您有一个包含1个字段的简单类:
[Serializable]
public class Test
{
public int A;
}
如果使用BinaryFormatter序列化一个数组,它将对Test的每个实例执行类似的操作:
int val = (int)typeof(Test).GetField("A").GetValue(obj);
var bytes = BitConverter.GetBytes(val);
stream.Write(bytes, 0, bytes.Length);
调用GetField()将花费大量时间。 您可以使用3种方法来显着提高速度:
手动序列化所有内容。 类似于以下代码:
void SimpleSerialize(Stream stream, Test[] arr) { foreach (var obj in arr) { var bytes = BitConverter.GetBytes(obj.A); stream.Write(bytes, 0, bytes.Length); } }
使用Reflection.Emit功能即时生成自定义序列化类。 这是更通用且“干净”的方法,但需要付出很多努力。
如果您满意,请使用一些适合您需要的第三方串行器 。
确实没有什么可以改进此代码的。 如果要处理简单的对象,则可以通过用BinaryWriter
替换BinaryFormatter
并手动序列化每个字段/属性来改进此代码,这将是最快的序列化。 但这是一个极端的措施,只有在实验确定该代码在某种程度上成为应用程序的瓶颈时,才应采取此措施。 否则,您可能会浪费时间进行微优化。
定义一个ThreadStatic byte[]
作为实例字段,并将其用作缓存。 将您的内存流包装在此缓存对象周围。 当您按代码编写使用MemoryStream
,将执行大量的分配,重新分配和数组复制步骤,因为MemoryStream
可以调整大小。 还需要考虑垃圾收集的成本。
可能的是,尽管我不确定这样做的效果如何,但是将两个格式化对象都缓存为ThreadStatic
实例字段。
PS,我确定这是一个错误,但是请注意,在使用MemoryStream
之前,请先对其进行处置。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.