在将程序更新为Java 11之后,使用xsl-fo(AWT渲染器)对XML的转换变得非常慢:Java 11:90秒Java 1.8:5秒
我没有用Java 9或10尝试过。
在Java 11和1.8之间运行时,没有代码,样式表也没有变化。
我在2.3版中使用org.apache.xmlgraphics:fop。
不幸的是,使用Saxon-HE 9.9.1-5(而不是Xalan)也没有改善性能。
通过分析和调试,看起来像org.apache.fop.layoutmgr.table.TableContentLayoutManager类中的代码行284占用了时间:
nextRowGroupElems = rowGroupLM.getNextKnuthElements(context, alignment, bodyType);
因此,罪魁祸首是使用AWT的Apache FOP。 使用MIME_PDF代替MIME_FOP_AWT_PREVIEW更快:5秒vs 90秒。
探查器(JProfiler)将java.awt.EventDispatchThread显示为Java 11的热点。因此,也许这是一个AWT问题。
复制相关代码:
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXResult;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.FopConfParser;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.FopFactoryBuilder;
import org.apache.fop.apps.MimeConstants;
import org.springframework.core.io.ClassPathResource;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
public class MyTransform {
public static void main(String[] args) throws Exception {
Document xmlDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new FileInputStream("my_xml.xml"));
Document xslDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File("my_xsl.xsl"));
Transformer transformer = TransformerFactory.newInstance().newTransformer(new DOMSource(xslDoc));
DOMSource xmlDomSource = new DOMSource(xmlDoc);
DOMResult domResult = new DOMResult();
transformer.transform(xmlDomSource, domResult);
Source src = new DOMSource(domResult.getNode());
Result res = new SAXResult(createFopFactory().newFop(MimeConstants.MIME_FOP_AWT_PREVIEW, getDisplayAgent()).getDefaultHandler());
TransformerFactory factory = javax.xml.transform.TransformerFactory.newInstance();
transformer = factory.newTransformer();
transformer.transform(src, res);
transformer.transform(src, res); // took with Java 11 90 seconds and with Java 1.8 5 seconds
}
private static FopFactory createFopFactory() throws SAXException, IOException {
ClassPathResource resource = new ClassPathResource("fop_configuration.xml");
FopConfParser parser = new FopConfParser(resource.getInputStream(), resource.getURI()); //parsing configuration
FopFactoryBuilder builder = parser.getFopFactoryBuilder(); //building the factory with the user options
return builder.build();
}
private static FOUserAgent getDisplayAgent() throws SAXException, IOException {
FopFactory fopFactory = createFopFactory();
FOUserAgent displayAgent = fopFactory.newFOUserAgent();
MyAWTRendererMaker maker = new MyAWTRendererMaker();
displayAgent.getRendererFactory().addRendererMaker(maker);
MyAWTRenderer displayRenderer = new MyAWTRenderer(displayAgent);
displayAgent.setRendererOverride(displayRenderer);
return displayAgent;
}
}