Sharing PreparedStylesheet the right way...
Added by Anonymous about 16 years ago
Legacy ID: #5247903 Legacy Poster: Alexandre Delarge (adelarge)
Hi, I'm using Saxon v8.7.3, and I'm caching compiled versions of XSL files in order to re-use it across multiple threads inside a web application. My question is related to the contention that happens on some of the underlying Saxon objects. Currently here is how I create the Saxon factory that will generate both my cached XSLT instances, and also standalone Saxon Transformer instances I may use. Note that I store one factory per execution thread: ----- // Create a Saxon Transformer/Templates factory TransformerFactory factory = TransformerFactoryImpl.newInstance(); // Use a distinct NamePool to avoid general contention on the default shared instance when creating Transformer instances through the factory ((TransformerFactoryImpl)factory).getConfiguration().setNamePool(new NamePool()); ----- And here is (basically) how I proceed to create and cache compiled instances: ----- // Get the XSL file as a source compatible object StreamSource xslt = new StreamSource(new FileInputStream(xslFile), xslFile.toURL().toExternalForm()); // Make a template from it using the thread's factory Templates template = factory.newTemplates(xslt); // Cache the template (simplified version...) cache.put(xslFile, template); ----- Now here is how I use the template: ----- // Retrieve the template (simplified version...) Templates template = cache.get(xslFile); // Create transformer Transformer tfm = template.newTransformer(); // Apply XSLT (input and output objects are supplied by the actual caller object) transformer.transform(in, out); ----- With my application running that code under stress conditions, I observe a recurring contention on the method "net.sf.saxon.om.NamePool.allocate". The pointed line in my thread dumps is "NamePool.java:433". I understand that actually all of the threads that use the template do share the same NamePool instance behind the PreparedStylesheet that is created when I compile the XSL file and cache it. As I understand it, the reason for that is the Controller object that is created via the call to "template.newTransformer()" does share its Configuration and Executable instance with the PreparedStylesheet. So I know that I could make my way to the NamePool instance that is used by each Transformer, and replace it with new instances in order to avoid re-using the one from the PreparedStylesheet. Unfortunately things don't seem to be that simple since method "transformDocument" in the Controller will check the same NamePool instance is used by both the input document and the target PreparedStylesheet. So my question is: how do I optimize the sharing of a same PreparedStylesheet across multiple threads ? The only 2 options I see are: - Make each thread use its own NamePool instance, and enforce its usage: is that enough or should I encounter issues in sharing other objects such as the PreparedStylesheet configuration, error listener, etc. ? - Should I perform a deep clone of the PreparedStylesheet, and would it address my need (and be efficient enough not to ruin the caching of the master PreparedStylesheet instance) ? Thanks a lot in advance for any advice on this topic. Regards, Alex.
Replies (3)
Please register to reply
RE: Sharing PreparedStylesheet the right way... - Added by Anonymous about 16 years ago
Legacy ID: #5247941 Legacy Poster: Michael Kay (mhkay)
The NamePool needs to be shared across threads. The important thing is that the integer codes placed in the compiled stylesheet need to be the same as the codes placed in a built source document, and this is only achieved by using the same NamePool. There's been quite a bit of work since 8.7 (the current release is 9.1) to reduce contention on the NamePool. I would suggest your first step should be to move forward to a later release. If you do need to partition the workload to reduce contention, you can always create an instance of the compiled stylesheet in each partition.
RE: Sharing PreparedStylesheet the right way... - Added by Anonymous about 16 years ago
Legacy ID: #5247950 Legacy Poster: Michael Kay (mhkay)
One thing that hasn't been fixed in more recent releases is that using external object models (DOM, JDOM etc) can lead to high contention on the NamePool (not to mention other significant inefficiencies). Avoid doing this if performance is important to you.
RE: Sharing PreparedStylesheet the right way... - Added by Anonymous about 16 years ago
Legacy ID: #5248412 Legacy Poster: Alexandre Delarge (adelarge)
Hi Michael, First, many thanks for these (very) fast replies. Second, you've guessed it: I'm unfortunately tied to using Xerces DOM objects as my input for XML transformations, and this for several reasons. And I cannot really get rid of it easily... Do you think that serializing the DOM to a string and reading inputs from strings (or from another model I could convert the DOM into) would improve things in a significant way ? (I'm only talking here about XSLT/XQuery processing in Saxon obviously) Besides, do you think that giving a try to Saxon v9.1x is useful knowing I'm relying on DOM inputs ? I'm not sure about that since you took the time to make a second post to mention the specific issue about external models. Thanks for your help. Best regards, Alex.
Please register to reply