Repository navigation
Very slow deserialization of XElement with text content using DataContractSerializer #37893
Description
Activity
- addeduntriagedNew issue has not been triaged by the area ownerNew issue has not been triaged by the area owner
on Jun 15, 2020 Interesting, its indeed very slow, but i don't think its caused from XElement, i did log the timing and it shows
XmlObjectSerializer.ReadObject(stream)is very slow:Stopwatch watch = Stopwatch.StartNew(); watch.Start(); var element = new XElement("element", string.Join("\r\n", Enumerable.Repeat(new string('a', 100), 100000))); Console.WriteLine(watch.ElapsedMilliseconds); // 78 watch.Restart(); var serializer = new DataContractSerializer(element.GetType()); using var memoryStream = new MemoryStream(); serializer.WriteObject(memoryStream, element); memoryStream.Seek(0, SeekOrigin.Begin); Console.WriteLine(watch.ElapsedMilliseconds); // 146 watch.Restart(); var deserialized = (XElement)serializer.ReadObject(memoryStream); Console.WriteLine(watch.ElapsedMilliseconds); // 30520
Event without casting to
XElementis the same, very slow. So changing the area toarea-Serialization. As @troplin mentioned changing the content to use "\r\n" instead of "\n" as line separator, the runtime is increased to almost 30 mins on my laptop, which is very very slow. Tagging @adamsitnik as he might want to see this, also tagging Runtime.Serialization area owners @StephenMolloy @HongGit@buyaa-n I've profiled the code and the time is lost in
XElement.AddStringSkipNotify(which is called fromDataContractSerializer.ReadObject, so you're not wrong).
The problem is (probably), that this method is called many times, each time with a small chunk of content which is then appended to theXElement.contentmember by string concatenation. This will allocate a new string each time, copying the previouscontentwhich grows larger each time.
This again leads to massive GC activity.- removeduntriagedNew issue has not been triaged by the area ownerNew issue has not been triaged by the area owner
on Jun 25, 2020 I can understand the frustration here, and we are going to keep this bug open to look at in a future milestone. 15 minutes is a long time to wait for a serializer. However, it is true that this is not a regression from the 4.8 framework.
What is probably happening here is that XElement likely already has custom serialization code to handle this case and thus can do things smartly and quickly, whereas DataContractSerializer is a general-purpose serializer that doesn't take those same shortcuts. It is almost always true that a special-purpose serializer will be faster than a general-purpose serializer for the case that it was specially designed for.
But again, 15 minutes is extreme. We will try to come back to this in the future. But we are quite low on resources and cannot prioritize this at this time given that it is not a regression from previous frameworks.
@StephenMolloy The strange thing is that it is as fast as expected when using
DataContractSerializertogether withXmlReaderandStringReaderto deserialize from a string.
Since that workaround works well, the issue is not really urgent right now.dotnet-policy-service commented
on Dec 27, 2024 ContributorMore actionsDue to lack of recent activity, this issue has been marked as a candidate for backlog cleanup. It will be closed if no further activity occurs within 14 more days. Any new comment (by anyone, not necessarily the author) will undo this process.
This process is part of our issue cleanup automation.
- addedbacklog-cleanup-candidateAn inactive issue that has been marked for automated closure.An inactive issue that has been marked for automated closure.
on Dec 27, 2024 - removedbacklog-cleanup-candidateAn inactive issue that has been marked for automated closure.An inactive issue that has been marked for automated closure.
on Jan 6, 2025 - addedin-prThere is an active PR which will close this issue when it is mergedThere is an active PR which will close this issue when it is merged
on Jul 16, 2026 This issue has been sitting with the serialization team for a while because it shows up in the performance of XmlSerializer... but the underlying cause is really in
XElement's implementation ofIXmlSerializable. I've thrown together a PR that should address the O(n) perf, and I'm reassigning to the Xml team so they can make a decision.dotnet-policy-service commented
on Jul 22, 2026 ContributorMore actionsTagging subscribers to this area: @dotnet/area-system-xml
See info in area-owners.md if you want to be subscribed.- added a commit that references this issue
on Aug 16, 2026 - added and removedin-prThere is an active PR which will close this issue when it is mergedThere is an active PR which will close this issue when it is merged
on Aug 16, 2026 - addedin-prThere is an active PR which will close this issue when it is mergedThere is an active PR which will close this issue when it is merged
on Aug 17, 2026
Description
The following code takes about 15 minutes to run on my machine:
The equivalent code using
SaveandLoadonly takes about 200-300 ms:Going through a string using
XmlWriter+StringWriter+XmlReader+StringReaderis also only 200-300 ms:Curiously, If I change the content to use
"\n"instead of"\r\n"as line separator, the runtime is reduced to about 15 s, which is still way too slow.Configuration
Analysis
My analysis shows, that the problem is excessive string concatenation in
XElement.AddStringSkipNotify. The content seems to arrive in very small chunks but I don't know the reason why.