3

I tried to make the serialization and deserialization of a custom object using the code below.

[Serializable]
public class TaskProperty
{
    public int Id { get; set; }
    public DateTime ScheduleTime { get; set; }
    public TimeSpan InitializationTime { get; set; }
    public Nullable<DateTime> InstantOfStart { get; set; }
    public TimeSpan TotalElapsedTime { get; set; }
}

// Main
var serializer = new DataContractSerializer(typeof(TaskProperty));
var reader = new FileStream("myfile.xml", FileMode.Open);
TaskProperty deserialized = (TaskProperty)(serializer.ReadObject(reader));
reader.Close();
Console.WriteLine("deserialized: {0}", deserialized);

If the TaskProperty class is decorated with DataContract attribute (and with DataMember attribute for each property), the deserialization is much faster than when it is decorated with Serializable attribute:

  • using DataContract and DataMember attributes, the deserialization is almost immediate;
  • using Serializable attribute, the deserialization is very slow (it takes about 30 seconds).

Why?

UPDATE... Furthermore, if the deserialization is preceded by the serialization of an object of the same type (obviously with different contents), the serialization is slow while the deserialization is fast. In a similar way, if serialization is preceded by deserializing an object of the same type, the deserialization is slow while the serialization is fast.

UPDATE 2... For completeness, I added the custom class that should be serialized and deserialized.

UPDATE 3... Well, maybe I discovered the cause of the slowness that affects the Serializable attribute, but I do not understand why. Essentially, if I explicitly declare the five private fields related to the five properties, as a consequence, the first serialization (or deserialization) is almost instant. Why?

enzom83
  • 8,080
  • 10
  • 68
  • 114
  • 1
    30 seconds sounds extreme, it hints at another cause. – H H Sep 07 '12 at 12:10
  • @HenkHolterman it's probably a very deep xml graph and the OP is likely running in debug mode that is creating the serializers on the fly lazily accounting for that huge lag instead of them NGEN'd out like release mode. – Chris Marisic Sep 07 '12 at 15:40
  • @ChrisMarisic: Just for completeness, the class to be serialized is quite simple: it contains two `DateTime` properties, two `TimeSpan` properties and one `int` property. – enzom83 Sep 07 '12 at 15:56
  • @enzom83 do multiple serializations not just once, i still expect that you're seeing the perf hit from your app dynamically creating the serializer it's using from not having it NGEN'd. – Chris Marisic Sep 07 '12 at 16:23
  • @ChrisMarisic: Performing multiple serializations, the average performance improves because only the first serialization is slower. – enzom83 Sep 07 '12 at 16:34

3 Answers3

1

I'm not 100% sure, but my guess is:

1) .NET embeds attribute information in the metadata of the assembly, so the data contract serializer doesn't have to do reflection to find all the data member attributes for a class.

2) Using [Serializable], the serializer inspects all fields of an object, and has to do this using reflection, which is costly.

armen.shimoon
  • 6,303
  • 24
  • 32
1

Just to comment on your update about serialization speeding up after the first call:

Likely the serializer is using reflection to build up the metadata and possibly a dynamic method to perform the serialization for that type, the first time it has to deal with that type.

I know if I was writing a generic serializer, thats what I would do; reflect over all the properties, ILEmit a dynamic method to perform the actual serialization, and save off that generated method to use whenever that same type is serialized or deserialized again.

CodingWithSpike
  • 42,906
  • 18
  • 101
  • 138
1

You probably are testing in debug mode and instead need to test in release mode that has your serializers properly NGEN'd.

Edit: regarding your comments above "the average performance improves because only the first serialization is slower." pretty much confirms my suspicions about lack of NGEN being the culprit. You need to review your project build settings under project properties < build < Generate serialization assembly

You want to verify that's not disabled for Release build (you can enable it for debug too if desired)

Some further information can be found:

XmlSerializer startup HUGE performance loss on 64bit systems

http://blogs.msdn.com/b/billwert/archive/2008/02/23/use-of-sgen-exe-to-avoid-common-xmlserializer-performance-pitfalls.aspx

Community
  • 1
  • 1
Chris Marisic
  • 32,487
  • 24
  • 164
  • 258