mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-07-30 22:43:14 +03:00
How to remove 20% of XSLT execution time in less than 20 lines of code
* xpath.c: started profiling XSLT, added xmlXPathNodeSetAddUnique() which removes a time consuming check of xmlXPathNodeSetAdd() and use it in places where we are sure to not break unicity Daniel
This commit is contained in:
@ -1,3 +1,9 @@
|
|||||||
|
Tue Feb 6 14:02:56 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
|
||||||
|
|
||||||
|
* xpath.c: started profiling XSLT, added xmlXPathNodeSetAddUnique()
|
||||||
|
which removes a time consuming check of xmlXPathNodeSetAdd()
|
||||||
|
and use it in places where we are sure to not break unicity
|
||||||
|
|
||||||
Mon Feb 5 18:51:36 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
|
Mon Feb 5 18:51:36 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
|
||||||
|
|
||||||
* xpath.c: bug fixes found from XSLT
|
* xpath.c: bug fixes found from XSLT
|
||||||
|
69
xpath.c
69
xpath.c
@ -669,6 +669,48 @@ xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) {
|
|||||||
cur->nodeTab[cur->nodeNr++] = val;
|
cur->nodeTab[cur->nodeNr++] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXPathNodeSetAddUnique:
|
||||||
|
* @cur: the initial node set
|
||||||
|
* @val: a new xmlNodePtr
|
||||||
|
*
|
||||||
|
* add a new xmlNodePtr ot an existing NodeSet, optimized version
|
||||||
|
* when we are sure the node is not already in the set.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) {
|
||||||
|
if (val == NULL) return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* grow the nodeTab if needed
|
||||||
|
*/
|
||||||
|
if (cur->nodeMax == 0) {
|
||||||
|
cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
|
||||||
|
sizeof(xmlNodePtr));
|
||||||
|
if (cur->nodeTab == NULL) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"xmlXPathNodeSetAddUnique: out of memory\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memset(cur->nodeTab, 0 ,
|
||||||
|
XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
|
||||||
|
cur->nodeMax = XML_NODESET_DEFAULT;
|
||||||
|
} else if (cur->nodeNr == cur->nodeMax) {
|
||||||
|
xmlNodePtr *temp;
|
||||||
|
|
||||||
|
cur->nodeMax *= 2;
|
||||||
|
temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
|
||||||
|
sizeof(xmlNodePtr));
|
||||||
|
if (temp == NULL) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"xmlXPathNodeSetAddUnique: out of memory\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cur->nodeTab = temp;
|
||||||
|
}
|
||||||
|
cur->nodeTab[cur->nodeNr++] = val;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlXPathNodeSetMerge:
|
* xmlXPathNodeSetMerge:
|
||||||
* @val1: the first NodeSet or NULL
|
* @val1: the first NodeSet or NULL
|
||||||
@ -943,7 +985,7 @@ xmlXPathNewNodeSetList(xmlNodeSetPtr val) {
|
|||||||
{
|
{
|
||||||
ret = xmlXPathNewNodeSet(val->nodeTab[0]);
|
ret = xmlXPathNewNodeSet(val->nodeTab[0]);
|
||||||
for (i = 1; i < val->nodeNr; ++i)
|
for (i = 1; i < val->nodeNr; ++i)
|
||||||
xmlXPathNodeSetAdd(ret->nodesetval, val->nodeTab[i]);
|
xmlXPathNodeSetAddUnique(ret->nodesetval, val->nodeTab[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(ret);
|
return(ret);
|
||||||
@ -2957,12 +2999,14 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, xmlXPathAxisVal axis,
|
|||||||
int i;
|
int i;
|
||||||
xmlNodeSetPtr ret;
|
xmlNodeSetPtr ret;
|
||||||
xmlXPathTraversalFunction next = NULL;
|
xmlXPathTraversalFunction next = NULL;
|
||||||
|
void (*addNode)(xmlNodeSetPtr, xmlNodePtr);
|
||||||
xmlNodePtr cur = NULL;
|
xmlNodePtr cur = NULL;
|
||||||
xmlXPathObjectPtr obj;
|
xmlXPathObjectPtr obj;
|
||||||
xmlNodeSetPtr nodelist;
|
xmlNodeSetPtr nodelist;
|
||||||
|
|
||||||
CHECK_TYPE(XPATH_NODESET);
|
CHECK_TYPE(XPATH_NODESET);
|
||||||
obj = valuePop(ctxt);
|
obj = valuePop(ctxt);
|
||||||
|
addNode = xmlXPathNodeSetAdd;
|
||||||
|
|
||||||
#ifdef DEBUG_STEP
|
#ifdef DEBUG_STEP
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
@ -3054,6 +3098,11 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, xmlXPathAxisVal axis,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
nodelist = obj->nodesetval;
|
nodelist = obj->nodesetval;
|
||||||
|
if ((nodelist != NULL) &&
|
||||||
|
(nodelist->nodeNr <= 1))
|
||||||
|
addNode = xmlXPathNodeSetAddUnique;
|
||||||
|
else
|
||||||
|
addNode = xmlXPathNodeSetAdd;
|
||||||
ret = xmlXPathNodeSetCreate(NULL);
|
ret = xmlXPathNodeSetCreate(NULL);
|
||||||
#ifdef DEBUG_STEP
|
#ifdef DEBUG_STEP
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
@ -3134,7 +3183,7 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, xmlXPathAxisVal axis,
|
|||||||
#ifdef DEBUG_STEP
|
#ifdef DEBUG_STEP
|
||||||
n++;
|
n++;
|
||||||
#endif
|
#endif
|
||||||
xmlXPathNodeSetAdd(ret, cur);
|
addNode(ret, cur);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NODE_TEST_PI:
|
case NODE_TEST_PI:
|
||||||
@ -3145,7 +3194,7 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, xmlXPathAxisVal axis,
|
|||||||
#ifdef DEBUG_STEP
|
#ifdef DEBUG_STEP
|
||||||
n++;
|
n++;
|
||||||
#endif
|
#endif
|
||||||
xmlXPathNodeSetAdd(ret, cur);
|
addNode(ret, cur);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NODE_TEST_ALL:
|
case NODE_TEST_ALL:
|
||||||
@ -3154,14 +3203,14 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, xmlXPathAxisVal axis,
|
|||||||
#ifdef DEBUG_STEP
|
#ifdef DEBUG_STEP
|
||||||
n++;
|
n++;
|
||||||
#endif
|
#endif
|
||||||
xmlXPathNodeSetAdd(ret, cur);
|
addNode(ret, cur);
|
||||||
}
|
}
|
||||||
} else if (axis == AXIS_NAMESPACE) {
|
} else if (axis == AXIS_NAMESPACE) {
|
||||||
if (cur->type == XML_NAMESPACE_DECL) {
|
if (cur->type == XML_NAMESPACE_DECL) {
|
||||||
#ifdef DEBUG_STEP
|
#ifdef DEBUG_STEP
|
||||||
n++;
|
n++;
|
||||||
#endif
|
#endif
|
||||||
xmlXPathNodeSetAdd(ret, cur);
|
addNode(ret, cur);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((cur->type == XML_ELEMENT_NODE) ||
|
if ((cur->type == XML_ELEMENT_NODE) ||
|
||||||
@ -3171,14 +3220,14 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, xmlXPathAxisVal axis,
|
|||||||
#ifdef DEBUG_STEP
|
#ifdef DEBUG_STEP
|
||||||
n++;
|
n++;
|
||||||
#endif
|
#endif
|
||||||
xmlXPathNodeSetAdd(ret, cur);
|
addNode(ret, cur);
|
||||||
} else if ((cur->ns != NULL) &&
|
} else if ((cur->ns != NULL) &&
|
||||||
(xmlStrEqual(prefix,
|
(xmlStrEqual(prefix,
|
||||||
cur->ns->href))) {
|
cur->ns->href))) {
|
||||||
#ifdef DEBUG_STEP
|
#ifdef DEBUG_STEP
|
||||||
n++;
|
n++;
|
||||||
#endif
|
#endif
|
||||||
xmlXPathNodeSetAdd(ret, cur);
|
addNode(ret, cur);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3197,7 +3246,7 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, xmlXPathAxisVal axis,
|
|||||||
#ifdef DEBUG_STEP
|
#ifdef DEBUG_STEP
|
||||||
n++;
|
n++;
|
||||||
#endif
|
#endif
|
||||||
xmlXPathNodeSetAdd(ret, cur);
|
addNode(ret, cur);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((cur->ns != NULL) &&
|
if ((cur->ns != NULL) &&
|
||||||
@ -3206,7 +3255,7 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, xmlXPathAxisVal axis,
|
|||||||
#ifdef DEBUG_STEP
|
#ifdef DEBUG_STEP
|
||||||
n++;
|
n++;
|
||||||
#endif
|
#endif
|
||||||
xmlXPathNodeSetAdd(ret, cur);
|
addNode(ret, cur);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3217,7 +3266,7 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, xmlXPathAxisVal axis,
|
|||||||
#ifdef DEBUG_STEP
|
#ifdef DEBUG_STEP
|
||||||
n++;
|
n++;
|
||||||
#endif
|
#endif
|
||||||
xmlXPathNodeSetAdd(ret, cur);
|
addNode(ret, cur);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user