mirror of
https://github.com/GNOME/libxml2.git
synced 2025-03-13 18:47:01 +08: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:
parent
9f7eb0bba3
commit
1989505ac7
@ -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
110
SAX2.c
@ -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;
|
||||
|
@ -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 */
|
||||
};
|
||||
|
||||
|
18
xmlreader.c
18
xmlreader.c
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user