[Mono-devel-list] Q. about implementation of serialization

Jonathan Gilbert 2a5gjx302 at sneakemail.com
Wed Oct 27 14:25:34 EDT 2004


At 01:42 PM 27/10/2004 +0200, Lluis Sanchez wrote:
[snip]
>Reflection is the only way you have to get information about the
>structure of objects, so yes, it is implemented using reflection.
>
>> I'm worrying that if reflection is involved for serialization, it may
>> have too much performance overhead.
>
>It is not overhead, since you can't do it in any other way.
[snip]

This isn't quite true. The old-fashioned way to serialize still works: just
define a method called 'Serialize' in each class you want to serialize that
does the actual work by hand. Since it's implemented within the same class,
the implementation details are known and no dynamic lookup is necessary.
For example:

class MyPoint
{
  public int X, Y;

  public void Serialize(BinaryWriter writer)
  {
    writer.Write(X);
    writer.Write(Y);
  }

  public static MyPoint Deserialize(BinaryReader reader)
  {
    MyPoint ret = new MyPoint();

    X = reader.ReadInt32();
    Y = reader.ReadInt32();

    return ret;
  }
}

class MyPointCollection
{
  ArrayList points = new ArrayList();

  public int Add(MyPoint pt) { return points.Add(pt); }
  public void RemoveAt(int idx) { points.RemoveAt(idx); }
  public MyPoint this[int idx]
  {
    get { return (MyPoint)points[idx]; }
    set { points[idx] = value; }
  }

  public void Serialize(BinaryWriter writer)
  {
    writer.Write(points.Count);
    foreach (MyPoint point in points)
      point.Serialize(writer);
  }

  public static MyPointCollection Deserialize(BinaryReader reader)
  {
    int num_points = reader.ReadInt32();

    MyPointCollection ret = new MyPointCollection();

    ret.points.Capacity = num_points;
    for (int i=0; i < num_points; i++)
      ret.points.Add(MyPoint.Deserialize(reader));

    return ret;
  }
}

Obviously, this is a high-maintenance way to serialize, but if performance
is an absolute must, this should perform MUCH better than reflection-based
automatic serialization (and should also produce smaller files). Of course,
care must be taken to ensure that the deserialization side of things can't
become desynchronized from the serialization side. This can happen even
accidentally (for instance, an ambiguity wrt the length of an encapsulated
item). One way to help ensure the correct serialized format is to have each
class insert and check for a magic number. Reflection-based serialization
does this, of course, in the form of the type descriptor of the class being
serialized. Another thing that helps is to store the length of the data
before the data so that if all else fails, you can simply seek past the end
of it to get to the next object (but usually you don't care about the next
object if the current one fails to deserialize :-).

Just my 2 cents :-)

Jonathan Gilbert




More information about the Mono-devel-list mailing list