Re: [xml] Performance patches for 2.4.22



Ouch!

From the experiments mentioned in earlier mails, I applied the 
three which are rather obviously non-breaking to 2.4.22

Fair punishment for careless use of "obvious".

I've attached a corrected diff for parser.c - in
xmlParseNameAndCompare the case of false
negative match due to end of buffer was not caught.
This will now work.

Peter Jacobi

BTW: On a Pentium 4 1.6GHz the gains are equal
or slightly better than on the PIII - strange Intel
processors:

Win2000 SP1 Pentium 4 1600 MHz Watcom C/C++ 11.0b

                Base    Patched

api.xml          70      61

api-e.xml        59      49

nethb.xml        14      13

nethb-e.xml      13      11

td.xml           53      46

Also, there is some better than clock-ratio
improvement over PIII, which I consider
very strange as I've seen a lot of code for
which a P4 MHz is only worth 0.7..0.8 PIII MHz.

And of couse, ye olde Watcom compiler is in
no way P4 aware (optimization switches end
at "Pentium Pro").


*** ..\2-4-22\parser.c  Fri May 10 04:35:14 2002
--- parser.c    Wed May 29 09:12:36 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,1797 ----
      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 (or end of input buffer), check with full function */
+     ret = xmlParseName (ctxt);
+     if (ret != 0 && xmlStrEqual (ret, other)) {
+       xmlFree (ret);
+       return (xmlChar*) 1;
+     }
+     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
--- 6602,6608 ----
      }
      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");
            }
  
        }     
--- 6624,6640 ----
       * 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) {
--- 6647,6654 ----
       */
      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) {


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