Java transformerFactory.newTransformer在测试过程中变慢
我有一个问题,我不知道根本原因到底是什么 我创建了javax.xml.transform.TransformerFactory的一个实例,然后直接解析xsltSource:Java transformerFactory.newTransformer在测试过程中变慢,java,xml,Java,Xml,我有一个问题,我不知道根本原因到底是什么 我创建了javax.xml.transform.TransformerFactory的一个实例,然后直接解析xsltSource: protected synchronized Transformer getTransformer(Source xsltSource) throws TransformerConfigurationException { TransformerFactory transformerFactory = Tr
protected synchronized Transformer getTransformer(Source xsltSource)
throws TransformerConfigurationException {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer(xsltSource);
return transformer;
}
现在我有一个测试,它是测试套件的一部分。当我独立运行该测试时,上面的代码持续大约1ms
当我作为测试套件的一部分运行该测试时,它需要更长的时间。这在eclipse和gradle中都会发生。
持续时间与之前运行的测试量成线性关系
它的数量级较慢,比如10-1000倍,这取决于在特定测试之前运行了多少测试
使用TransformerFactory的缓存实例将把测试时间缩短一半。但症状仍然相同。我一直在分析它,但没有看到任何可疑的东西,除了测试需要更长的时间 你知道这是什么原因吗 编辑我正在使用com.sun.org.apache.xalan.internal.xsltc.trax.transformerfactorympl com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl 课程。
我想哪些是JDK提供的 Edit2我假设它与加载的类的数量有关(这是在测试运行期间发生变化的一件事)。因此,可以为单个测试任意加载类,但不会更改计时。因此,这里加载的类的数量似乎不是问题所在 Edit3我将saxon解析器添加到我的类路径中,并特别提到了该类路径:
TransformerFactory transformerFactory = TransformerFactory.newInstance("net.sf.saxon.TransformerFactoryImpl", null);
TransformerImpl transformer = (TransformerImpl) transformerFactory.newTransformer(xsltSource);
行为仍然是一样的,独立测试运行得很快,但作为测试套件的一部分,它要慢得多
Edit4我对这行代码有相同的行为:
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
它会变慢,在特定测试之前运行的测试越多,但如果独立执行,则不会变慢
经过两天的挖掘,xalan花费的时间越来越多,类路径上的路径也越来越多。
它使用sun.misc.CompoundEnumeration类遍历它,寻找SaxParserFactory的实现,这需要越来越长的时间,我们运行的测试越多,因为它们填满了类路径,类加载器必须搜索更多的类。
事实上,在过去的几天里,我发现了我们真正的问题所在
在我们的算法中,我们1.经常创建TemplateFactory的新实例
2.经常创建SAXParserFactory的新实例
3.没有缓存我们经常重新编译的模板,而 是一样的 因此,解决方案是创建TemplateFactory的一个实例并 在SAXParserfactory中,确保它们不运行多线程并传递 它们沿着调用链向下移动,并缓存我们的一个模板和 重复使用 最后但并非最不重要的一点是,我发现JDK 用于查找TemplateFactory的实现,以及 使用ServiceLoader的SAXParserFactory。花了很长时间 eclipse中的时间,以及ServiceLoader看起来的位置 对于随着时间的推移而被填满的实现(您可以在 ServiceLoader的文档,实际发生这种情况的地方)。 为这些的默认实现传递系统属性 接口也会解决这个问题 总而言之,我们的绩效提高了90%以上:-) 编辑根据要求,我将不添加属性本身,而是添加一个指向javadoc的链接,该链接准确地解释了发生的情况以及您必须执行的操作: 这些是javax.xml.transform.TransformerFactory和javax.xml.parsers.SAXParserFactory属性,但是,设置它的内容取决于使用哪个JDK和/或解析器库 经过两天的挖掘,xalan花费的时间越来越多,类路径上的路径也越来越多。 它使用sun.misc.CompoundEnumeration类遍历它,寻找SaxParserFactory的实现,这需要越来越长的时间,我们运行的测试越多,因为它们填满了类路径,类加载器必须搜索更多的类。 事实上,在过去的几天里,我发现了我们真正的问题所在 在我们的算法中,我们
1.经常创建TemplateFactory的新实例
2.经常创建SAXParserFactory的新实例
3.没有缓存我们经常重新编译的模板,而 是一样的 因此,解决方案是创建TemplateFactory的一个实例并 在SAXParserfactory中,确保它们不运行多线程并传递 它们沿着调用链向下移动,并缓存我们的一个模板和 重复使用 最后但并非最不重要的一点是,我发现JDK 用于查找TemplateFactory的实现,以及 使用ServiceLoader的SAXParserFactory。花了很长时间 eclipse中的时间,以及ServiceLoader看起来的位置 对于随着时间的推移而被填满的实现(您可以在 ServiceLoader的文档,实际发生这种情况的地方)。 为这些的默认实现传递系统属性 接口也会解决这个问题 总而言之,我们的绩效提高了90%以上:-) 编辑根据要求,我将不添加属性本身,而是添加一个指向javadoc的链接,该链接准确地解释了发生的情况以及您必须执行的操作:
这些是javax.xml.transform.TransformerFactory和javax.xml.parsers.SAXParserFactory的属性,但是,您将其设置为什么,取决于您使用的JDK和/或解析器库。您实际使用的xml转换器是什么?内置的?沙兰?撒克逊人?等等,等等。您实际使用的xml转换器是什么?内置的?沙兰?撒克逊人?为了完整性,您可以添加设置系统属性的位置和方式吗?为了完整性,您可以添加设置系统属性的位置和方式吗?