5

I have recently upgraded the .NET framework on my machine to .NET 4.6 and have noticed a big difference in times of binary (de)serialization of objects from/to files.

For example, I have a 10MB file which was deserialized in ~2 seconds on my machine with .NET 4.5.2. After upgrading to .NET 4.6 it takes up to 50 seconds(!) - actual time is pretty random: sometimes it takes 2 seconds, sometimes 50 seconds (same file, same program, even same process).

Has anybody else noticed similar behavior and maybe found a workaround (or solution) for this issue?

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
Bartek
  • 73
  • 3
  • 7
    Can you prove your statement with code? The question "Sometimes something doesn't work" will probably get closed. What effort did you put in research before asking? – netaholic Aug 28 '15 at 12:15
  • Well, my program is pretty complex (I serialize objects with hundreds of fields) but I will try to find a smaller example of the problem. I have tried to find any information about changes (or problems) related to .NET 4.6 but so far I haven't found any (although there are evidences of some severe problems existing in .NET 4.6's RyuJIT, so maybe serialization problems is somehow related as well) – Bartek Aug 28 '15 at 12:18
  • Are you (de)serialising classes or structs? – Wai Ha Lee Aug 28 '15 at 12:45
  • Also, is this problem a problem for both x86 and x64? – Wai Ha Lee Aug 28 '15 at 12:47
  • 1
    You need to create a prototype that serializes and deserializes that 10mb file and see if you can reproduce the slowness. If you can, submit a connect to microsoft about it, as it may be a bug. –  Aug 28 '15 at 12:56
  • 1
    ... We had the following problem at my work: x86 was unaffected, but x64 was. The problem is that we were deserialising lots of classes (not structs) **in parallel**. We got in touch with Microsoft and they suggested a few workarounds: (a) Change the items you are (de)serialising to structs, (b) Create serialisation surrogates which implement `ISerializationSurrogate` as a shim to permit the classes to be serialised as structs. If my situation sounds familiar, our feedback from Microsoft was that it's an issue in 4.6 but could be fixed in 4.6.1. – Wai Ha Lee Aug 28 '15 at 13:02
  • I'm serializing classes (in fact complex object graphs, including inheritance, generics etc.). I am trying to replicate the problem with simple dummy class with 200 fields, but so far without success. – Bartek Aug 28 '15 at 13:16
  • @WaiHaLee: this seems to be exactly the same problem as I am experiencing (although I deserialize one file only, not in parallel). I have just tested and problem does not occur on code compiled in x86 version. Unfortunately, switching to structs in not an option for me right now. Do you have any reference to MS bug id regarding the problem you mentioned? – Bartek Aug 28 '15 at 13:26
  • I'm not at liberty to give any much more details than that (sorry), but I can say that the solution we went down was to use [protobuf](https://developers.google.com/protocol-buffers) to do our (de)serialisation. We have about 50,000 objects which we were using Microsoft's serialsation for. We found that the time taken to deserialise was nonlinear in the number of items, so we split the objects into six files (30MB total), hence the parallelisation. Using protobuf, we have all the data in one (~20MB) file, but I don't suppose that is an option to you. Sorry I can't be of more help to you. – Wai Ha Lee Aug 28 '15 at 14:06
  • Are you seeing slow deserialization times *only* whilst debugging? I'm experiencing a similar issue but with SOAP XML deserialization, see http://stackoverflow.com/questions/34047995/incredibly-slow-debugging-after-installing-visual-studio-2015-update-1 – Alex Dec 02 '15 at 16:56

2 Answers2

5

Little reason to assume it has anything to do with binary serialization, it is pretty deterministic. Given the random behavior and the likelihood that you'll poke the garbage collector pretty heavily with a 10 megabyte file, a very good candidate is this bug. Quite a doozy.

If you have a good repro then use the new Diagnostics Tools to see any slow gen #1 collections. And tinker with GCSettings.LatencyMode, if it has an affect then you know it is the underlying cause. Should be fixed soon.

Community
  • 1
  • 1
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Thanks for this hint. I have added a thread that monitors percentage of time spent in GC. It turned out in these critical places (during/after deserialization) 99% of time is spent in GC (with default settings). When I changed to GCLatencyMode.LowLatency then it was no longer blocking and % of GC time was like 50% or so. – Bartek Aug 31 '15 at 11:46
  • 1
    Score one for psychic debugging. – Hans Passant Aug 31 '15 at 13:09
  • love to read answers like this. That identifies the question as a symptom and answers with a solution to the real problem. – jgauffin May 09 '16 at 06:18
0

We encountered exactly the same problem with the BinaryFormatter when deserializing objects. As we observed this is due to a bug in framework 4.6 which is resolved in framework 4.6.1. The list of changes are found here. The offending bug is Improved performance of parallel binary file deserialization [141896].

participant
  • 2,923
  • 2
  • 23
  • 40