As you might know, ajaxslt is used by the Selenium framework for XPath evaluation in browsers like IE that don't have native XPath support for HTML documents. The slowness of evaluation as compared to native methods has been a common complaint.
I'm wondering if ajaxslt XPath functionality has ever been profiled to determine performance bottlenecks / inner loops to optimize / slowness due to recursion? Does a corpus of XPath expressions and their associated documents exist that may be used for such a test? I'd be interested in doing this, or seeing the results if someone has done it already.
Given no response so far, it seems this hasn't been done. :) So I went ahead and performed some simple tests. I saved the HTML content of select pages, and inserted the import commands for ajaxslt (misc.js, dom.js, and xpath.js ... these came with my Selenium distribution). Then I constructed a non-trivial, valid XPath for each page, and evaluated the it in javascript. Then I profiled the page load for each case using Firebug. Here are my test files:
Notice there were no results for the myspace page ... execution of the XPath evaluation caused the script to hang! Consider this a bug report. :)
As one might expect, which functions were most heavily used depended on the composition of the XPath expression. However, the library will clearly see a speed boost if optimizations can be performed on the following functions, which were invoked thousands to ten-thousands of times, and which consumed ~10%+ of the total execution time:
copyArray() clone() ExprContext() evaluate() - line 793 xpathCollectDescendants() evaluate() - line 645
Note there are different flavors of the evaluate method.
NodeTestName.prototype.evaluate = function(ctx) { var n = ctx.node; // NOTE (Patrick Lightbody): this change allows node selection to be case-insensitive return new BooleanValue(n.nodeName.toUpperCase() == this.name.toUpperCase());
}
If reverted to:
NodeTestName.prototype.evaluate = function(ctx) { return new BooleanValue(ctx.node == this.name);
}
The "Percent" value drops from 15.3% down to an amazing 4.5%. Can anyone comment on how useful the same-cased comparison is, or even if it works? In my own testing for the UI-Element extension, I've had to use a separate home-grown (and possibly incomplete) function to uppercase the element names in the XPath. Possibly relevant Selenium thread:
function xpathCollectDescendants(nodelist, node) { for (var n = node.firstChild; n; n = n.nextSibling) { nodelist.push(n); arguments.callee(nodelist, n); }
}
can be changed to
function xpathCollectDescendants(nodelist, node) { for (var n = node.firstChild; n; n = n.nextSibling) { nodelist.push(n); xpathCollectDescendants(nodelist, n); }
}
for an improvement of a few percentage points, to around 16.9%. There's another occurrence of arguments.callee which can be replaced too. It occurs to me that any of these tweaks could have different results for different browsers ... anyone with an IE profiler out there?
Looks like the case-insensitive comparison code isn't in source ... must have picked it up as part of a Selenium hack. Well, it's good to know that that modification is solely responsible for halving XPath performance. Gotta take that out.
Aside from that change, implementing the other changes above results in a 7.7% speed improvement over the base code. It's not much, but it's something. Of course the unit test suite would have to be run to verify these changes ... and I don't have all the browsers to test against. :) Any javascript optimizing gurus out there want to give this a shot?
I'm not a guru but thanks for doing this excellent work; I hope it gets considered for incorporation. I've had to reconsider using AJAXSLT in a project because of the performance issues in some areas. It turned out to be better overall for me to restrict my users to Mozilla and just use TransforMiix.
> Looks like the case-insensitive comparison code isn't in source ... > must have picked it up as part of a Selenium hack. Well, it's good to > know that that modification is solely responsible for halving XPath > performance. Gotta take that out.
> Aside from that change, implementing the other changes above results > in a 7.7% speed improvement over the base code. It's not much, but > it's something. Of course the unit test suite would have to be run to > verify these changes ... and I don't have all the browsers to test > against. :) Any javascript optimizing gurus out there want to give > this a shot?