[no subject]



They give up to 20% performance increase in cases I'm 
interested in, on a moderately slow system (PII-350),
somewhat less on a P3-1000 and -I hope- somewhat
more on the 100MHz PC104 boards.

See measurement results below.

The diffs are attached (zipped and plain). They consist of:

- name ownership taking versions of xmlNewNode,
xmlNewDocNode and xmlNewNsProp. The original
versions are unchanged, but to clean up, in an exchange
for one extra function call, the original versions may
better be implemented as in
xmlNewNode(...name..) {
        return xmlNewNodeEatName(...xmlStrdup(name)...);
}

- disinlining all but the first line of SHRINK and GROW

- specialised function xmlParseNameAndCompare
for endtag parsing, which can avoid one malloc and some
processing in all but the nonWF-error case.

Regards,
Peter Jacobi

Benchmarks done using statically linked xmllint, all options disabled.

api.xml [500k] : the libxml-api.xml file from 2.4.22
api-e.xml [592k] : that file, with all attributes XSLT transformed into 
elements
nethb.xml [75k] : biomed amplifier status file
nethb-e.xml [98k] : that file, with all attributes XSLT transformed into 
elements
td.xml [489k]: save file from a board game design app

xmllint --noout --timing --repeat

numbers are ms / iteration

WinNT 4 SP5 Pentium II 350 MHz Watcom C/C++ 11.0b

                Base    Patched

api.xml         349     300

api-e.xml       290     229

nethb.xml        68     58

nethb-e.xml      66     52

td.xml          275     229



Win2000 SP1 Pentium III 1000 MHz Watcom C/C++ 11.0b

                Base    Patched

api.xml         120     108

api-e.xml       102      85

nethb.xml        23      21

nethb-e.xml      23      19

td.xml           96      84



--Message-Boundary-28614
Content-type: Application/ZIP; name="ppatch-diffs.zip"
Content-disposition: attachment; filename="ppatch-diffs.zip"
Content-transfer-encoding: BASE64

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
UEsFBgAAAAAEAAQA5QAAABUOAAAAAA==

--Message-Boundary-28614
Content-type: text/plain; charset=US-ASCII
Content-transfer-encoding: 7BIT
Content-description: Text from file 'sax.c.diff'

*** ..\2-4-22\sax.c     Mon Mar 25 16:50:04 2002
--- sax.c       Tue May 28 20:42:08 2002
***************
*** 907,913 ****
      }
  
      /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com";> */
!     ret = xmlNewNsProp(ctxt->node, namespace, name, NULL);
  
      if (ret != NULL) {
          if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
--- 907,913 ----
      }
  
      /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com";> */
!     ret = xmlNewNsPropEatName(ctxt->node, namespace, name, NULL);
  
      if (ret != NULL) {
          if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
***************
*** 984,991 ****
  
      if (nval != NULL)
        xmlFree(nval);
-     if (name != NULL) 
-       xmlFree(name);
      if (ns != NULL) 
        xmlFree(ns);
  }
--- 984,989 ----
***************
*** 1194,1200 ****
       *        attributes parsing, since local namespace can be defined as
       *        an attribute at this level.
       */
!     ret = xmlNewDocNode(ctxt->myDoc, NULL, name, NULL);
      if (ret == NULL) return;
      if (ctxt->myDoc->children == NULL) {
  #ifdef DEBUG_SAX_TREE
--- 1192,1198 ----
       *        attributes parsing, since local namespace can be defined as
       *        an attribute at this level.
       */
!     ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL, name, NULL);
      if (ret == NULL) return;
      if (ctxt->myDoc->children == NULL) {
  #ifdef DEBUG_SAX_TREE
***************
*** 1334,1341 ****
  
      if (prefix != NULL)
        xmlFree(prefix);
-     if (name != NULL)
-       xmlFree(name);
  
  }
  
--- 1332,1337 ----

--Message-Boundary-28614
Content-type: text/plain; charset=US-ASCII
Content-transfer-encoding: 7BIT
Content-description: Text from file 'parser.c.diff'

*** ..\2-4-22\parser.c  Fri May 10 04:35:14 2002
--- parser.c    Tue May 28 21:22:25 2002
***************
*** 281,298 ****
            xmlPopInput(ctxt);                                          \
    } while (0)
  
! #define SHRINK if (ctxt->input->cur - ctxt->input->base > INPUT_CHUNK) {\
!     xmlParserInputShrink(ctxt->input);                                        \
!     if ((*ctxt->input->cur == 0) &&                                   \
!         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))          \
!           xmlPopInput(ctxt);                                          \
    }
  
! #define GROW if (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK) { \
!     xmlParserInputGrow(ctxt->input, INPUT_CHUNK);                     \
!     if ((*ctxt->input->cur == 0) &&                                   \
!         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))          \
!           xmlPopInput(ctxt);                                          \
    }
  
  #define SKIP_BLANKS xmlSkipBlankChars(ctxt)
--- 281,304 ----
            xmlPopInput(ctxt);                                          \
    } while (0)
  
! #define SHRINK if (ctxt->input->cur - ctxt->input->base > INPUT_CHUNK) \
!       xmlSHRINK (ctxt);
! 
! static void xmlSHRINK (xmlParserCtxtPtr ctxt) {
!     xmlParserInputShrink(ctxt->input);
!     if ((*ctxt->input->cur == 0) &&
!         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
!           xmlPopInput(ctxt);
    }
  
! #define GROW if (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK) \
!       xmlGROW (ctxt);
! 
! static void xmlGROW (xmlParserCtxtPtr ctxt) {
!     xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
!     if ((*ctxt->input->cur == 0) &&
!         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
!           xmlPopInput(ctxt);
    }
  
  #define SKIP_BLANKS xmlSkipBlankChars(ctxt)
***************
*** 1746,1751 ****
--- 1752,1793 ----
      return(xmlParseNameComplex(ctxt));
  }
  
+ /**
+  * xmlParseNameAndCompare:
+  * @ctxt:  an XML parser context
+  *
+  * parse an XML name and compares for match
+  * (specialized for endtag parsing)
+  *
+  *
+  * Returns NULL for an illegal name, (xmlChar*) 1 for success
+  * and the name for mismatch
+  */
+ 
+ xmlChar *
+ xmlParseNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *other) {
+     const xmlChar *cmp = other;
+     const xmlChar *in;
+     xmlChar *ret;
+     int count = 0;
+ 
+     GROW;
+     
+     in = ctxt->input->cur;
+     while (*in != 0 && *in == *cmp) {
+       ++in;
+       ++cmp;
+     }
+     if (*cmp == 0 && (*in == '>' || IS_BLANK (*in))) {
+       /* success */
+       ctxt->input->cur = in;
+       return (xmlChar*) 1;
+     }
+     /* failure, decide why */
+     ret = xmlParseName (ctxt);
+     return ret;
+ }
+ 
  static xmlChar *
  xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
      xmlChar buf[XML_MAX_NAMELEN + 5];
***************
*** 6556,6562 ****
      }
      SKIP(2);
  
!     name = xmlParseName(ctxt);
  
      /*
       * We should definitely be at the ending "S? '>'" part
--- 6598,6604 ----
      }
      SKIP(2);
  
!     name = xmlParseNameAndCompare(ctxt,ctxt->name);
  
      /*
       * We should definitely be at the ending "S? '>'" part
***************
*** 6578,6597 ****
       * start-tag. 
       *
       */
!     if ((name == NULL) || (ctxt->name == NULL) ||
!         (!xmlStrEqual(name, ctxt->name))) {
        ctxt->errNo = XML_ERR_TAG_NAME_MISMATCH;
        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) {
!           if ((name != NULL) && (ctxt->name != NULL)) {
                ctxt->sax->error(ctxt->userData,
                     "Opening and ending tag mismatch: %s and %s\n",
                                 ctxt->name, name);
!             } else if (ctxt->name != NULL) {
                ctxt->sax->error(ctxt->userData,
                     "Ending tag error for: %s\n", ctxt->name);
-           } else {
-               ctxt->sax->error(ctxt->userData,
-                    "Ending tag error: internal error ???\n");
            }
  
        }     
--- 6620,6636 ----
       * start-tag. 
       *
       */
!     if (name != (xmlChar*)1) {
        ctxt->errNo = XML_ERR_TAG_NAME_MISMATCH;
        if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) {
!           if (name != NULL) {
                ctxt->sax->error(ctxt->userData,
                     "Opening and ending tag mismatch: %s and %s\n",
                                 ctxt->name, name);
!               xmlFree(name);           
!             } else {
                ctxt->sax->error(ctxt->userData,
                     "Ending tag error for: %s\n", ctxt->name);
            }
  
        }     
***************
*** 6604,6613 ****
       */
      if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
        (!ctxt->disableSAX))
!         ctxt->sax->endElement(ctxt->userData, name);
  
-     if (name != NULL)
-       xmlFree(name);
      oldname = namePop(ctxt);
      spacePop(ctxt);
      if (oldname != NULL) {
--- 6643,6650 ----
       */
      if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
        (!ctxt->disableSAX))
!         ctxt->sax->endElement(ctxt->userData, ctxt->name);
  
      oldname = namePop(ctxt);
      spacePop(ctxt);
      if (oldname != NULL) {

--Message-Boundary-28614
Content-type: text/plain; charset=US-ASCII
Content-transfer-encoding: 7BIT
Content-description: Text from file 'tree.c.diff'

*** ..\2-4-22\tree.c    Sat May 25 04:35:18 2002
--- tree.c      Tue May 28 20:40:36 2002
***************
*** 1204,1209 ****
--- 1204,1286 ----
  }
  
  /**
+  * xmlNewNsPropEatName:
+  * @node:  the holding node
+  * @ns:  the namespace
+  * @name:  the name of the attribute
+  * @value:  the value of the attribute
+  *
+  * Create a new property tagged with a namespace and carried by a node.
+  * Returns a pointer to the attribute
+  */
+ xmlAttrPtr
+ xmlNewNsPropEatName(xmlNodePtr node, xmlNsPtr ns, xmlChar *name,
+            const xmlChar *value) {
+     xmlAttrPtr cur;
+     xmlDocPtr doc = NULL;
+ 
+     if (name == NULL) {
+ #ifdef DEBUG_TREE
+         xmlGenericError(xmlGenericErrorContext,
+               "xmlNewNsPropEatName : name == NULL\n");
+ #endif
+       return(NULL);
+     }
+ 
+     /*
+      * Allocate a new property and fill the fields.
+      */
+     cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr));
+     if (cur == NULL) {
+         xmlGenericError(xmlGenericErrorContext,
+               "xmlNewNsPropEatName : malloc failed\n");
+       return(NULL);
+     }
+     memset(cur, 0, sizeof(xmlAttr));
+     cur->type = XML_ATTRIBUTE_NODE;
+ 
+     cur->parent = node; 
+     if (node != NULL) {
+       doc = node->doc;
+       cur->doc = doc;
+     }
+     cur->ns = ns;
+     cur->name = name;
+     if (value != NULL) {
+       xmlChar *buffer;
+       xmlNodePtr tmp;
+ 
+       buffer = xmlEncodeEntitiesReentrant(doc, value);
+       cur->children = xmlStringGetNodeList(doc, buffer);
+       cur->last = NULL;
+       tmp = cur->children;
+       while (tmp != NULL) {
+           tmp->parent = (xmlNodePtr) cur;
+           if (tmp->next == NULL)
+               cur->last = tmp;
+           tmp = tmp->next;
+       }
+       xmlFree(buffer);
+     }
+ 
+     /*
+      * Add it at the end to preserve parsing order ...
+      */
+     if (node != NULL) {
+       if (node->properties == NULL) {
+           node->properties = cur;
+       } else {
+           xmlAttrPtr prev = node->properties;
+ 
+           while (prev->next != NULL) prev = prev->next;
+           prev->next = cur;
+           cur->prev = prev;
+       }
+     }
+     return(cur);
+ }
+ 
+ /**
   * xmlNewDocProp:
   * @doc:  the document
   * @name:  the name of the attribute
***************
*** 1432,1437 ****
--- 1509,1552 ----
  }
  
  /**
+  * xmlNewNodeEatName:
+  * @ns:  namespace if any
+  * @name:  the node name
+  *
+  * Creation of a new node element. @ns is optional (NULL).
+  *
+  * Returns a pointer to the new node object.
+  */
+ xmlNodePtr
+ xmlNewNodeEatName(xmlNsPtr ns, xmlChar *name) {
+     xmlNodePtr cur;
+ 
+     if (name == NULL) {
+ #ifdef DEBUG_TREE
+         xmlGenericError(xmlGenericErrorContext,
+               "xmlNewNode : name == NULL\n");
+ #endif
+       return(NULL);
+     }
+ 
+     /*
+      * Allocate a new node and fill the fields.
+      */
+     cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
+     if (cur == NULL) {
+         xmlGenericError(xmlGenericErrorContext,
+               "xmlNewNode : malloc failed\n");
+       return(NULL);
+     }
+     memset(cur, 0, sizeof(xmlNode));
+     cur->type = XML_ELEMENT_NODE;
+     
+     cur->name = name;
+     cur->ns = ns;
+     return(cur);
+ }
+ 
+ /**
   * xmlNewDocNode:
   * @doc:  the document
   * @ns:  namespace if any
***************
*** 1453,1458 ****
--- 1568,1605 ----
      xmlNodePtr cur;
  
      cur = xmlNewNode(ns, name);
+     if (cur != NULL) {
+         cur->doc = doc;
+       if (content != NULL) {
+           cur->children = xmlStringGetNodeList(doc, content);
+           UPDATE_LAST_CHILD_AND_PARENT(cur)
+       }
+     }
+     return(cur);
+ }
+ 
+ /**
+  * xmlNewDocNodeEatName:
+  * @doc:  the document
+  * @ns:  namespace if any
+  * @name:  the node name
+  * @content:  the XML text content if any
+  *
+  * Creation of a new node element within a document. @ns and @content
+  * are optional (NULL).
+  * NOTE: @content is supposed to be a piece of XML CDATA, so it allow entities
+  *       references, but XML special chars need to be escaped first by using
+  *       xmlEncodeEntitiesReentrant(). Use xmlNewDocRawNode() if you don't
+  *       need entities support.
+  *
+  * Returns a pointer to the new node object.
+  */
+ xmlNodePtr
+ xmlNewDocNodeEatName(xmlDocPtr doc, xmlNsPtr ns,
+               xmlChar *name, const xmlChar *content) {
+     xmlNodePtr cur;
+ 
+     cur = xmlNewNodeEatName(ns, name);
      if (cur != NULL) {
          cur->doc = doc;
        if (content != NULL) {

--Message-Boundary-28614
Content-type: text/plain; charset=US-ASCII
Content-transfer-encoding: 7BIT
Content-description: Text from file 'tree.h.diff'

*** ..\2-4-22\include\libxml\tree.h     Thu Apr 18 04:35:16 2002
--- include\libxml\tree.h       Tue May 28 20:32:23 2002
***************
*** 591,596 ****
--- 591,600 ----
                                         xmlNsPtr ns,
                                         const xmlChar *name,
                                         const xmlChar *value);
+ xmlAttrPtr    xmlNewNsPropEatName     (xmlNodePtr node,
+                                        xmlNsPtr ns,
+                                        xmlChar *name,
+                                        const xmlChar *value);
  void          xmlFreePropList         (xmlAttrPtr cur);
  void          xmlFreeProp             (xmlAttrPtr cur);
  xmlAttrPtr    xmlCopyProp             (xmlNodePtr target,
***************
*** 608,619 ****
--- 612,629 ----
                                         xmlNsPtr ns,
                                         const xmlChar *name,
                                         const xmlChar *content);
+ xmlNodePtr    xmlNewDocNodeEatName    (xmlDocPtr doc,
+                                        xmlNsPtr ns,
+                                        xmlChar *name,
+                                        const xmlChar *content);
  xmlNodePtr    xmlNewDocRawNode        (xmlDocPtr doc,
                                         xmlNsPtr ns,
                                         const xmlChar *name,
                                         const xmlChar *content);
  xmlNodePtr    xmlNewNode              (xmlNsPtr ns,
                                         const xmlChar *name);
+ xmlNodePtr    xmlNewNodeEatName       (xmlNsPtr ns,
+                                        xmlChar *name);
  xmlNodePtr    xmlNewChild             (xmlNodePtr parent,
                                         xmlNsPtr ns,
                                         const xmlChar *name,

--Message-Boundary-28614--



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]