-
Bug
-
Resolution: Fixed
-
P4
-
1.2.3
-
1.3
-
x86
-
windows_xp
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2098559 | 5.0 | Arun Yadav | P4 | Resolved | Fixed | b55 |
Name: gm110360 Date: 05/13/2004
FULL PRODUCT VERSION :
1.5.0-beta-b32c
ADDITIONAL OS VERSION INFORMATION :
Windows XP (5.1, Build 2600.xpsp2.030...)
A DESCRIPTION OF THE PROBLEM :
[Note: I posted this against JAXP 1.2.3 as there is no selection for Tiger]
I'm using Tiger's XSLTC with extension functions. One of my functions returns a org.w3c.dom.NodeList which XSLTC translates into a an internal DOM iterator (see com.sun.org.apache.xalan.internal.xsltc.runtime.BasisLibrary#nodeList2Iterator).
This method is called after each invocation of the extension function. Each time it will locate a Dom implementation through the JAXP factory interface. This is a very expensive operation as it searches through the whole classpath. It actually dominates processing time, as I can see when doing threaddumps.
After replacing that code to create a new org.apache.xerces.dom.DocumentImpl, I got a factor of 5 higher transformation throughput. In a setting with more complicated classloaders as in a J2EE container, the impact is likely to be even higher.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
From a stylesheet, call an extension function that returns a NodeList:
<xsl:template match="*">
<xsl:copy-of select="java:my.Class.function()" />
</xsl:template>
with
Class {
static final NodeList result = DocumentBuilder.newInstance().newDocument().createDocumentFragment().getChildNodes();
public static NodeList function() {
return result;
}
}
Call this transformation in a loop. Do threaddumps.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Speedy transformations. No anomalies in the stack traces.
ACTUAL -
Transformation was rather slow (1.6ms). After the proposed change it was down to 0.4ms
The following fragment was dominating the processing time:
"main" prio=5 tid=0x0003e210 nid=0x874 runnable [0x0007e000..0x0007fc3c]
at java.io.BufferedReader.<init>(BufferedReader.java:91)
at org.apache.xerces.util.ObjectFactory.findJarServiceProvider(Unknown Source)
at org.apache.xerces.util.ObjectFactory.createObject(Unknown Source)
at org.apache.xerces.util.ObjectFactory.createObject(Unknown Source)
at org.apache.xerces.parsers.DOMParser.<init>(Unknown Source)
at org.apache.xerces.parsers.DOMParser.<init>(Unknown Source)
at org.apache.xerces.jaxp.DocumentBuilderImpl.<init>(Unknown Source)
at org.apache.xerces.jaxp.DocumentBuilderFactoryImpl.newDocumentBuilder(Unknown Source)
at com.sun.org.apache.xalan.internal.xsltc.runtime.BasisLibrary.nodeList2Iterator(BasisLibrary.java:1172)
at GregorSamsa.template$dot$0()
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
/*
* Copyright (c) 2004 CoreMedia AG, Hamburg. All rights reserved.
*/
package test;
import org.w3c.dom.NodeList;
import javax.xml.transform.Templates;
import javax.xml.transform.TransformerException;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.ByteArrayOutputStream;
import java.io.StringReader;
public class XsltPerformance {
public static void main(String[] args) throws TransformerException {
String xml = "<root/>";
String xsl =
"<xsl:transform version=\"1.0\"\n" +
" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"\n" +
" xmlns:java=\"http://xml.apache.org/xalan/java\"\n" +
" exclude-result-prefixes=\"java\"\n" +
" >" +
" <xsl:template match=\"/\">" +
" <xsl:copy-of select=\"java:test.XsltPerformance.empty()\"/> "+
" </xsl:template>"+
"</xsl:transform>";
Templates templates = new com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl().newTemplates(new StreamSource(new StringReader(xsl)));
while(true) {
StreamResult devNull = new StreamResult(new ByteArrayOutputStream());
long start = System.currentTimeMillis();
for(int i=0; i<1000; i++) {
templates.newTransformer().transform(new StreamSource(new StringReader(xml)), devNull);
}
System.out.println(System.currentTimeMillis()-start);
}
}
static final NodeList EMPTY = new com.sun.org.apache.xerces.internal.dom.DocumentImpl().createDocumentFragment().getChildNodes();
public static NodeList empty() {
return EMPTY;
}
}
---------- END SOURCE ----------
(Incident Review ID: 265357)
======================================================================
FULL PRODUCT VERSION :
1.5.0-beta-b32c
ADDITIONAL OS VERSION INFORMATION :
Windows XP (5.1, Build 2600.xpsp2.030...)
A DESCRIPTION OF THE PROBLEM :
[Note: I posted this against JAXP 1.2.3 as there is no selection for Tiger]
I'm using Tiger's XSLTC with extension functions. One of my functions returns a org.w3c.dom.NodeList which XSLTC translates into a an internal DOM iterator (see com.sun.org.apache.xalan.internal.xsltc.runtime.BasisLibrary#nodeList2Iterator).
This method is called after each invocation of the extension function. Each time it will locate a Dom implementation through the JAXP factory interface. This is a very expensive operation as it searches through the whole classpath. It actually dominates processing time, as I can see when doing threaddumps.
After replacing that code to create a new org.apache.xerces.dom.DocumentImpl, I got a factor of 5 higher transformation throughput. In a setting with more complicated classloaders as in a J2EE container, the impact is likely to be even higher.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
From a stylesheet, call an extension function that returns a NodeList:
<xsl:template match="*">
<xsl:copy-of select="java:my.Class.function()" />
</xsl:template>
with
Class {
static final NodeList result = DocumentBuilder.newInstance().newDocument().createDocumentFragment().getChildNodes();
public static NodeList function() {
return result;
}
}
Call this transformation in a loop. Do threaddumps.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Speedy transformations. No anomalies in the stack traces.
ACTUAL -
Transformation was rather slow (1.6ms). After the proposed change it was down to 0.4ms
The following fragment was dominating the processing time:
"main" prio=5 tid=0x0003e210 nid=0x874 runnable [0x0007e000..0x0007fc3c]
at java.io.BufferedReader.<init>(BufferedReader.java:91)
at org.apache.xerces.util.ObjectFactory.findJarServiceProvider(Unknown Source)
at org.apache.xerces.util.ObjectFactory.createObject(Unknown Source)
at org.apache.xerces.util.ObjectFactory.createObject(Unknown Source)
at org.apache.xerces.parsers.DOMParser.<init>(Unknown Source)
at org.apache.xerces.parsers.DOMParser.<init>(Unknown Source)
at org.apache.xerces.jaxp.DocumentBuilderImpl.<init>(Unknown Source)
at org.apache.xerces.jaxp.DocumentBuilderFactoryImpl.newDocumentBuilder(Unknown Source)
at com.sun.org.apache.xalan.internal.xsltc.runtime.BasisLibrary.nodeList2Iterator(BasisLibrary.java:1172)
at GregorSamsa.template$dot$0()
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
/*
* Copyright (c) 2004 CoreMedia AG, Hamburg. All rights reserved.
*/
package test;
import org.w3c.dom.NodeList;
import javax.xml.transform.Templates;
import javax.xml.transform.TransformerException;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.ByteArrayOutputStream;
import java.io.StringReader;
public class XsltPerformance {
public static void main(String[] args) throws TransformerException {
String xml = "<root/>";
String xsl =
"<xsl:transform version=\"1.0\"\n" +
" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"\n" +
" xmlns:java=\"http://xml.apache.org/xalan/java\"\n" +
" exclude-result-prefixes=\"java\"\n" +
" >" +
" <xsl:template match=\"/\">" +
" <xsl:copy-of select=\"java:test.XsltPerformance.empty()\"/> "+
" </xsl:template>"+
"</xsl:transform>";
Templates templates = new com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl().newTemplates(new StreamSource(new StringReader(xsl)));
while(true) {
StreamResult devNull = new StreamResult(new ByteArrayOutputStream());
long start = System.currentTimeMillis();
for(int i=0; i<1000; i++) {
templates.newTransformer().transform(new StreamSource(new StringReader(xml)), devNull);
}
System.out.println(System.currentTimeMillis()-start);
}
}
static final NodeList EMPTY = new com.sun.org.apache.xerces.internal.dom.DocumentImpl().createDocumentFragment().getChildNodes();
public static NodeList empty() {
return EMPTY;
}
}
---------- END SOURCE ----------
(Incident Review ID: 265357)
======================================================================
- backported by
-
JDK-2098559 Tiger's XSLTC uses DocumentBuilderFactory lookup for each NodeList result
- Resolved
-
JDK-2098560 Tiger's XSLTC uses DocumentBuilderFactory lookup for each NodeList result
- Resolved