Observe the following .NET type:
public class X
{
public DateTime Timestamp {get;set;}
public double Value {get;set;}
public double Min {get;set;}
public double Max {get;set;}
}
I need to convert an array of N elements of X to a single byte array and vice versa efficiently and the code must be Silverlight compatible (meaning forget about the binary serialization, be it efficient or not).
My solution is:
public void GetState(SerializationInfo info)
{
var stream = new MemoryStream();
var buf = BitConverter.GetBytes(Count);
stream.Write(buf, 0, buf.Length);
foreach (var item in this)
{
buf = BitConverter.GetBytes(item.Timestamp.Ticks);
stream.Write(buf, 0, buf.Length);
buf = BitConverter.GetBytes(item.Value);
stream.Write(buf, 0, buf.Length);
buf = BitConverter.GetBytes(item.Min);
stream.Write(buf, 0, buf.Length);
buf = BitConverter.GetBytes(item.Max);
stream.Write(buf, 0, buf.Length);
}
info.AddValue("Data", stream.ToArray());
}
public void SetState(SerializationInfo info)
{
var data = info.GetValue<byte[]>("Data");
int count = BitConverter.ToInt32(data, 0);
Capacity = count;
int offset = sizeof(int);
while (count-- > 0)
{
Add(new ExtendedNormalizedSample(
new DateTime(BitConverter.ToInt64(data, offset)),
BitConverter.ToDouble(data, offset += sizeof(long)),
BitConverter.ToDouble(data, offset += sizeof(double)),
BitConverter.ToDouble(data, offset += sizeof(double))));
offset += sizeof(double);
}
}
(Ignore the SerializationInfo stuff – irrelevant for the question)
Anyway, what I do not like about my solution is the abundance of byte[] arrays created during the serialization. I mean, every call to BitConverter.GetBytes returns a new byte array and although, creating new byte arrays is cheap in .NET, but still, as a former C++ developer, this seems to be an awful waste to use a new byte array each time, whereas a single byte array can be reused.
Can anyone suggest a better solution (remember, it must be Silverlight compatible, so do not propose unsafe code).
Thanks.
The
DateTimeTickscould be encoded as an integer via shift operations etc. Thefloat– you might try using a union to swap forint, and then encode theintwith shift operations:Then if you have an existing
Streamorbyte[]you can encode (depending on your chosen endianness) something like: