From f132f642b23d9d0c336354a0bc4bb95c41023c34 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 28 Aug 2014 18:15:33 +0100 Subject: On code section that rezzes single objects and attachments, reduce CPU use by reading asset XML a single time with a stream reader rather than multiple times. Reading large XML documents (e.g. complex attachments) is CPU expensive - this must be done as few times as possible (preferably just once). Reading these documents into XmlDocument is also more resource intensive than using XmlTextReader, as per Microsoft's own publication "Improve .NET Application Performance and Scalability" Optimization of other cases will follow if this change is successful. --- .../Scenes/Serialization/SceneObjectSerializer.cs | 67 +++++++++++----------- 1 file changed, 34 insertions(+), 33 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes/Serialization') diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index e68f954..8f99dc6 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -59,57 +59,58 @@ namespace OpenSim.Region.Framework.Scenes.Serialization /// The scene object deserialized. Null on failure. public static SceneObjectGroup FromOriginalXmlFormat(string xmlData) { + using (XmlTextReader reader = new XmlTextReader(xmlData, XmlNodeType.Element, null)) + return FromOriginalXmlFormat(reader); + } + + /// + /// Deserialize a scene object from the original xml format + /// + /// + /// The scene object deserialized. Null on failure. + public static SceneObjectGroup FromOriginalXmlFormat(XmlTextReader reader) + { //m_log.DebugFormat("[SOG]: Starting deserialization of SOG"); //int time = System.Environment.TickCount; + SceneObjectGroup sceneObject = null; + try { - StringReader sr; - XmlTextReader reader; - XmlNodeList parts; - XmlDocument doc; int linkNum; - doc = new XmlDocument(); - doc.LoadXml(xmlData); - parts = doc.GetElementsByTagName("RootPart"); + reader.ReadToFollowing("RootPart"); + reader.ReadToFollowing("SceneObjectPart"); + sceneObject = new SceneObjectGroup(SceneObjectPart.FromXml(reader)); + reader.ReadToFollowing("OtherParts"); - if (parts.Count == 0) - throw new Exception("Invalid Xml format - no root part"); - - sr = new StringReader(parts[0].InnerXml); - reader = new XmlTextReader(sr); - SceneObjectGroup sceneObject = new SceneObjectGroup(SceneObjectPart.FromXml(reader)); - reader.Close(); - sr.Close(); - - parts = doc.GetElementsByTagName("Part"); - - for (int i = 0; i < parts.Count; i++) + if (reader.ReadToDescendant("Part")) { - sr = new StringReader(parts[i].InnerXml); - reader = new XmlTextReader(sr); - SceneObjectPart part = SceneObjectPart.FromXml(reader); - linkNum = part.LinkNum; - sceneObject.AddPart(part); - part.LinkNum = linkNum; - part.TrimPermissions(); - reader.Close(); - sr.Close(); + do + { + if (reader.ReadToDescendant("SceneObjectPart")) + { + SceneObjectPart part = SceneObjectPart.FromXml(reader); + linkNum = part.LinkNum; + sceneObject.AddPart(part); + part.LinkNum = linkNum; + part.TrimPermissions(); + } + } + while (reader.ReadToNextSibling("Part")); } // Script state may, or may not, exist. Not having any, is NOT // ever a problem. - sceneObject.LoadScriptState(doc); - - return sceneObject; + sceneObject.LoadScriptState(reader); } catch (Exception e) { - m_log.ErrorFormat( - "[SERIALIZER]: Deserialization of xml failed with {0}. xml was {1}", e, xmlData); + m_log.ErrorFormat("[SERIALIZER]: Deserialization of xml failed. Exception {0}", e); return null; } + + return sceneObject; } /// -- cgit v1.1