From 2c257ec1ee03356abb49670ac7c1ddb34e404844 Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Tue, 6 Feb 2001 13:29:07 +0000 Subject: [PATCH] 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 --- ChangeLog | 6 +++++ xpath.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 65 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 27e83630..bdc71de6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Tue Feb 6 14:02:56 CET 2001 Daniel Veillard + + * 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 * xpath.c: bug fixes found from XSLT diff --git a/xpath.c b/xpath.c index fde7c3ba..00ded9ce 100644 --- a/xpath.c +++ b/xpath.c @@ -669,6 +669,48 @@ xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr 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: * @val1: the first NodeSet or NULL @@ -943,7 +985,7 @@ xmlXPathNewNodeSetList(xmlNodeSetPtr val) { { ret = xmlXPathNewNodeSet(val->nodeTab[0]); for (i = 1; i < val->nodeNr; ++i) - xmlXPathNodeSetAdd(ret->nodesetval, val->nodeTab[i]); + xmlXPathNodeSetAddUnique(ret->nodesetval, val->nodeTab[i]); } return(ret); @@ -2957,12 +2999,14 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, xmlXPathAxisVal axis, int i; xmlNodeSetPtr ret; xmlXPathTraversalFunction next = NULL; + void (*addNode)(xmlNodeSetPtr, xmlNodePtr); xmlNodePtr cur = NULL; xmlXPathObjectPtr obj; xmlNodeSetPtr nodelist; CHECK_TYPE(XPATH_NODESET); obj = valuePop(ctxt); + addNode = xmlXPathNodeSetAdd; #ifdef DEBUG_STEP xmlGenericError(xmlGenericErrorContext, @@ -3054,6 +3098,11 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, xmlXPathAxisVal axis, return; nodelist = obj->nodesetval; + if ((nodelist != NULL) && + (nodelist->nodeNr <= 1)) + addNode = xmlXPathNodeSetAddUnique; + else + addNode = xmlXPathNodeSetAdd; ret = xmlXPathNodeSetCreate(NULL); #ifdef DEBUG_STEP xmlGenericError(xmlGenericErrorContext, @@ -3134,7 +3183,7 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, xmlXPathAxisVal axis, #ifdef DEBUG_STEP n++; #endif - xmlXPathNodeSetAdd(ret, cur); + addNode(ret, cur); } break; case NODE_TEST_PI: @@ -3145,7 +3194,7 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, xmlXPathAxisVal axis, #ifdef DEBUG_STEP n++; #endif - xmlXPathNodeSetAdd(ret, cur); + addNode(ret, cur); } break; case NODE_TEST_ALL: @@ -3154,14 +3203,14 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, xmlXPathAxisVal axis, #ifdef DEBUG_STEP n++; #endif - xmlXPathNodeSetAdd(ret, cur); + addNode(ret, cur); } } else if (axis == AXIS_NAMESPACE) { if (cur->type == XML_NAMESPACE_DECL) { #ifdef DEBUG_STEP n++; #endif - xmlXPathNodeSetAdd(ret, cur); + addNode(ret, cur); } } else { if ((cur->type == XML_ELEMENT_NODE) || @@ -3171,14 +3220,14 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, xmlXPathAxisVal axis, #ifdef DEBUG_STEP n++; #endif - xmlXPathNodeSetAdd(ret, cur); + addNode(ret, cur); } else if ((cur->ns != NULL) && (xmlStrEqual(prefix, cur->ns->href))) { #ifdef DEBUG_STEP n++; #endif - xmlXPathNodeSetAdd(ret, cur); + addNode(ret, cur); } } } @@ -3197,7 +3246,7 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, xmlXPathAxisVal axis, #ifdef DEBUG_STEP n++; #endif - xmlXPathNodeSetAdd(ret, cur); + addNode(ret, cur); } } else { if ((cur->ns != NULL) && @@ -3206,7 +3255,7 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, xmlXPathAxisVal axis, #ifdef DEBUG_STEP n++; #endif - xmlXPathNodeSetAdd(ret, cur); + addNode(ret, cur); } } } @@ -3217,7 +3266,7 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, xmlXPathAxisVal axis, #ifdef DEBUG_STEP n++; #endif - xmlXPathNodeSetAdd(ret, cur); + addNode(ret, cur); } break; }