Use references rather than copying containers in libpbd xml code
authorTim Mayberry <mojofunk@gmail.com>
Thu, 22 Sep 2016 12:38:12 +0000 (22:38 +1000)
committerTim Mayberry <mojofunk@gmail.com>
Sun, 9 Oct 2016 22:45:34 +0000 (08:45 +1000)
It is slightly surprising but there seems to be little difference to
performance with these changes. Possibly a slight improvement in "Create" test
with a large xml document(~5%).

Timing results before these changes with an optimized build using new XML perf tests:

XMLTest::testPerfMediumXMLDocumentTiming
   Create : Count: 10 Min: 38656 Max: 63827 Total: 571228 Avg: 57122 (57 msecs)
   Write : Count: 10 Min: 43594 Max: 49279 Total: 459907 Avg: 45990 (45 msecs)
   Read : Count: 10 Min: 80247 Max: 84912 Total: 827207 Avg: 82720 (82 msecs)

XMLTest::testPerfLargeXMLDocumentTiming
   Create : Count: 10 Min: 230706 Max: 456054 Total: 3850998 Avg: 385099 (385 msecs)
   Write : Count: 10 Min: 312322 Max: 353789 Total: 3264211 Avg: 326421 (326 msecs)
   Read : Count: 10 Min: 573556 Max: 610865 Total: 5951908 Avg: 595190 (595 msecs)

Timing results after these changes:

XMLTest::testPerfMediumXMLDocumentTiming
   Create : Count: 10 Min: 41293 Max: 63746 Total: 564448 Avg: 56444 (56 msecs)
   Write : Count: 10 Min: 42932 Max: 49221 Total: 453955 Avg: 45395 (45 msecs)
   Read : Count: 10 Min: 80160 Max: 84678 Total: 824506 Avg: 82450 (82 msecs)

XMLTest::testPerfLargeXMLDocumentTiming
   Create : Count: 10 Min: 228759 Max: 420236 Total: 3587597 Avg: 358759 (358 msecs)
   Write : Count: 10 Min: 307095 Max: 348767 Total: 3205704 Avg: 320570 (320 msecs)
   Read : Count: 10 Min: 572400 Max: 657219 Total: 5959630 Avg: 595963 (595 msecs)

libs/pbd/xml++.cc

index b12eb69252c06e69ea84e2683b2fbde97ac42e88..2db08eb3e2cc4eb699e17f212fb93aaeb9f4c3bb 100644 (file)
@@ -263,27 +263,24 @@ XMLNode::clear_lists ()
 XMLNode&
 XMLNode::operator= (const XMLNode& from)
 {
-       if (&from != this) {
+       if (&from == this) {
+               return *this;
+       }
 
-               XMLPropertyList props;
-               XMLPropertyIterator curprop;
-               XMLNodeList nodes;
-               XMLNodeIterator curnode;
+       clear_lists ();
 
-               clear_lists ();
+       _name = from.name ();
+       set_content (from.content ());
 
-               _name = from.name();
-               set_content(from.content());
+       const XMLPropertyList& props = from.properties ();
 
-               props = from.properties();
-               for (curprop = props.begin(); curprop != props.end(); ++curprop) {
-                       add_property((*curprop)->name().c_str(), (*curprop)->value());
-               }
+       for (XMLPropertyConstIterator prop_iter = props.begin (); prop_iter != props.end (); ++prop_iter) {
+               add_property ((*prop_iter)->name ().c_str (), (*prop_iter)->value ());
+       }
 
-               nodes = from.children();
-               for (curnode = nodes.begin(); curnode != nodes.end(); ++curnode) {
-                       add_child_copy(**curnode);
-               }
+       const XMLNodeList& nodes = from.children ();
+       for (XMLNodeConstIterator child_iter = nodes.begin (); child_iter != nodes.end (); ++child_iter) {
+               add_child_copy (**child_iter);
        }
 
        return *this;
@@ -693,10 +690,6 @@ readnode(xmlNodePtr node)
 static void
 writenode(xmlDocPtr doc, XMLNode* n, xmlNodePtr p, int root = 0)
 {
-       XMLPropertyList props;
-       XMLPropertyIterator curprop;
-       XMLNodeList children;
-       XMLNodeIterator curchild;
        xmlNodePtr node;
 
        if (root) {
@@ -710,14 +703,18 @@ writenode(xmlDocPtr doc, XMLNode* n, xmlNodePtr p, int root = 0)
                xmlNodeSetContentLen(node, (const xmlChar*)n->content().c_str(), n->content().length());
        }
 
-       props = n->properties();
-       for (curprop = props.begin(); curprop != props.end(); ++curprop) {
-               xmlSetProp(node, (const xmlChar*) (*curprop)->name().c_str(), (const xmlChar*) (*curprop)->value().c_str());
+       const XMLPropertyList& props = n->properties();
+
+       for (XMLPropertyConstIterator prop_iter = props.begin (); prop_iter != props.end ();
+            ++prop_iter) {
+               xmlSetProp (node, (const xmlChar*)(*prop_iter)->name ().c_str (),
+                           (const xmlChar*)(*prop_iter)->value ().c_str ());
        }
 
-       children = n->children();
-       for (curchild = children.begin(); curchild != children.end(); ++curchild) {
-               writenode(doc, *curchild, node);
+       const XMLNodeList& children = n->children ();
+       for (XMLNodeConstIterator child_iter = children.begin (); child_iter != children.end ();
+            ++child_iter) {
+               writenode (doc, *child_iter, node);
        }
 }