1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2024-10-26 12:25:09 +03:00

more performance hunting reducing memory allocation and free and avoiding

* SAX2.c xmlreader.c include/libxml/parser.h: more performance hunting
  reducing memory allocation and free and avoiding expensive routines
Daniel
This commit is contained in:
Daniel Veillard 2003-09-17 13:59:32 +00:00
parent 9f7eb0bba3
commit 1989505ac7
4 changed files with 104 additions and 31 deletions

View File

@ -1,3 +1,8 @@
Wed Sep 17 15:57:44 CEST 2003 Daniel Veillard <daniel@veillard.com>
* SAX2.c xmlreader.c include/libxml/parser.h: more performance hunting
reducing memory allocation and free and avoiding expensive routines
Wed Sep 17 12:23:41 CEST 2003 Daniel Veillard <daniel@veillard.com>
* SAX2.c parser.c parserInternals.c xmlreader.c: started messing

110
SAX2.c
View File

@ -1564,6 +1564,47 @@ xmlSAX2EndElement(void *ctx, const xmlChar *name ATTRIBUTE_UNUSED)
nodePop(ctxt);
}
/*
* xmlSAX2TextNode:
* @ctxt: the parser context
* @str: the input string
* @len: the string length
*
* Remove the entities from an attribute value
*
* Returns the newly allocated string or NULL if not needed or error
*/
static xmlNodePtr
xmlSAX2TextNode(xmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
xmlNodePtr ret;
if (ctxt->freeElems != NULL) {
ret = ctxt->freeElems;
ctxt->freeElems = ret->next;
ctxt->freeElemsNr--;
memset(ret, 0, sizeof(xmlNode));
ret->type = XML_TEXT_NODE;
ret->name = xmlStringText;
ret->content = xmlStrndup(str, len);
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
xmlRegisterNodeDefaultValue(ret);
} else {
ret = xmlNewTextLen(str, len);
}
if (ret == NULL) {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
"SAX.xmlSAX2Characters(): out of memory\n");
ctxt->errNo = XML_ERR_NO_MEMORY;
ctxt->instate = XML_PARSER_EOF;
ctxt->disableSAX = 1;
return(NULL);
}
return(ret);
}
/*
* xmlSAX2DecodeAttrEntities:
* @ctxt: the parser context
@ -1630,6 +1671,7 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
if (ctxt->freeAttrs != NULL) {
ret = ctxt->freeAttrs;
ctxt->freeAttrs = ret->next;
ctxt->freeAttrsNr--;
memset(ret, 0, sizeof(xmlAttr));
ret->type = XML_ATTRIBUTE_NODE;
@ -1672,21 +1714,40 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
xmlNodePtr tmp;
ret->children = xmlStringLenGetNodeList(ctxt->myDoc, value,
valueend - value);
tmp = ret->children;
while (tmp != NULL) {
tmp->parent = (xmlNodePtr) ret;
if (tmp->next == NULL)
ret->last = tmp;
tmp = tmp->next;
/*
* We know that if there is an entity reference, then
* the string has been dup'ed and terminates with 0
* otherwise with ' or "
*/
if (*valueend != 0) {
tmp = xmlSAX2TextNode(ctxt, value, valueend - value);
ret->children = tmp;
ret->last = tmp;
if (tmp != NULL) {
tmp->doc = ret->doc;
tmp->parent = (xmlNodePtr) ret;
}
} else {
ret->children = xmlStringLenGetNodeList(ctxt->myDoc, value,
valueend - value);
tmp = ret->children;
while (tmp != NULL) {
tmp->parent = (xmlNodePtr) ret;
if (tmp->next == NULL)
ret->last = tmp;
tmp = tmp->next;
}
}
} else if (value != NULL) {
ret->children = xmlNewDocTextLen(ctxt->myDoc, value,
valueend - value);
ret->last = ret->children;
if (ret->children != NULL)
ret->children->parent = (xmlNodePtr) ret;
xmlNodePtr tmp;
tmp = xmlSAX2TextNode(ctxt, value, valueend - value);
ret->children = tmp;
ret->last = tmp;
if (tmp != NULL) {
tmp->doc = ret->doc;
tmp->parent = (xmlNodePtr) ret;
}
}
if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
@ -1837,6 +1898,7 @@ xmlSAX2StartElementNs(void *ctx,
if (ctxt->freeElems != NULL) {
ret = ctxt->freeElems;
ctxt->freeElems = ret->next;
ctxt->freeElemsNr--;
memset(ret, 0, sizeof(xmlNode));
ret->type = XML_ELEMENT_NODE;
@ -2056,7 +2118,7 @@ xmlSAX2Characters(void *ctx, const xmlChar *ch, int len)
#endif
return;
}
lastChild = xmlGetLastChild(ctxt->node);
lastChild = ctxt->node->last;
#ifdef DEBUG_SAX_TREE
xmlGenericError(xmlGenericErrorContext,
"add chars to %s \n", ctxt->node->name);
@ -2067,9 +2129,12 @@ xmlSAX2Characters(void *ctx, const xmlChar *ch, int len)
* elements. Use an attribute in the structure !!!
*/
if (lastChild == NULL) {
/* first node, first time */
xmlNodeAddContentLen(ctxt->node, ch, len);
if (ctxt->node->children != NULL) {
lastChild = xmlSAX2TextNode(ctxt, ch, len);
if (lastChild != NULL) {
ctxt->node->children = lastChild;
ctxt->node->last = lastChild;
lastChild->parent = ctxt->node;
lastChild->doc = ctxt->node->doc;
ctxt->nodelen = len;
ctxt->nodemem = len + 1;
}
@ -2122,15 +2187,8 @@ xmlSAX2Characters(void *ctx, const xmlChar *ch, int len)
}
} else {
/* Mixed content, first time */
lastChild = xmlNewTextLen(ch, len);
if (lastChild == NULL) {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
"SAX.xmlSAX2Characters(): out of memory\n");
ctxt->errNo = XML_ERR_NO_MEMORY;
ctxt->instate = XML_PARSER_EOF;
ctxt->disableSAX = 1;
} else {
lastChild = xmlSAX2TextNode(ctxt, ch, len);
if (lastChild != NULL) {
xmlAddChild(ctxt->node, lastChild);
if (ctxt->node->children != NULL) {
ctxt->nodelen = len;

View File

@ -267,7 +267,9 @@ struct _xmlParserCtxt {
* Those fields are needed only for treaming parsing so far
*/
int dictNames; /* Use dictionary names for the tree */
int freeElemsNr; /* number of freed element nodes */
xmlNodePtr freeElems; /* List of freed element nodes */
int freeAttrsNr; /* number of freed attributes nodes */
xmlAttrPtr freeAttrs; /* List of freed attributes nodes */
};

View File

@ -263,9 +263,11 @@ xmlTextReaderFreeProp(xmlTextReaderPtr reader, xmlAttrPtr cur) {
(xmlDictOwns(reader->ctxt->dict, cur->name) != 1) &&
(cur->name != NULL))
xmlFree((xmlChar *)cur->name);
if ((reader != NULL) && (reader->ctxt != NULL)) {
if ((reader != NULL) && (reader->ctxt != NULL) &&
(reader->ctxt->freeAttrsNr < 100)) {
cur->next = reader->ctxt->freeAttrs;
reader->ctxt->freeAttrs = cur;
reader->ctxt->freeAttrsNr++;
} else {
xmlFree(cur);
}
@ -347,10 +349,13 @@ xmlTextReaderFreeNodeList(xmlTextReaderPtr reader, xmlNodePtr cur) {
(cur->type != XML_COMMENT_NODE) &&
(cur->name != NULL))
xmlFree((xmlChar *)cur->name);
if ((cur->type == XML_ELEMENT_NODE) &&
(reader != NULL) && (reader->ctxt != NULL)) {
if (((cur->type == XML_ELEMENT_NODE) ||
(cur->type == XML_TEXT_NODE)) &&
(reader != NULL) && (reader->ctxt != NULL) &&
(reader->ctxt->freeElemsNr < 100)) {
cur->next = reader->ctxt->freeElems;
reader->ctxt->freeElems = cur;
reader->ctxt->freeElemsNr++;
} else {
xmlFree(cur);
}
@ -414,10 +419,13 @@ xmlTextReaderFreeNode(xmlTextReaderPtr reader, xmlNodePtr cur) {
(cur->type != XML_COMMENT_NODE) &&
(cur->name != NULL))
xmlFree((xmlChar *)cur->name);
if ((cur->type == XML_ELEMENT_NODE) &&
(reader != NULL) && (reader->ctxt != NULL)) {
if (((cur->type == XML_ELEMENT_NODE) ||
(cur->type == XML_TEXT_NODE)) &&
(reader != NULL) && (reader->ctxt != NULL) &&
(reader->ctxt->freeElemsNr < 100)) {
cur->next = reader->ctxt->freeElems;
reader->ctxt->freeElems = cur;
reader->ctxt->freeElemsNr++;
} else {
xmlFree(cur);
}