On Wednesday, February 20, 2013, Michael Kay wrote:
Another possible culprit is the call on preceding::* in
node()[preceding::*[. intersect $docNodes] is $final]
I think the question here is, how big is $docNodes? Testing the
intersect operator will be linear in the size of $docNodes.
This seems to be the issue. A small document with 40 $docNodes runs in about a second, while a more typical document has about 800 $docNodes and takes 1.5 hours. There are quite a lot of expressions that do an intersection test, so switching to a set of keys will definitely help.
Once again your undisputed mastery of XSLT lights the way.