gpt4 book ai didi

java - TransformerFactory.newTransformer 在测试期间变得更慢

转载 作者:太空宇宙 更新时间:2023-11-04 11:44:10 30 4
gpt4 key购买 nike

我遇到一个问题,我不知道根本原因到底是什么。

我创建了 javax.xml.transform.TransformerFactory 的实例,然后直接解析 xsltSource:

protected synchronized Transformer getTransformer(Source xsltSource)
throws TransformerConfigurationException {

TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer(xsltSource);
return transformer;
}

现在我有一个测试,它是测试套件的一部分。当我独立运行该测试时,上面的代码持续大约需要 1 毫秒。

当我将该测试作为测试套件的一部分运行时,需要更长的时间。这种情况在 eclipse 和 gradle 中都会发生。持续时间随着之前运行的测试数量线性增加。

其速度要慢几个数量级,例如 10 - 1000 倍,具体取决于特定测试之前运行的测试数量。

使用 TransfomerFactory 的缓存实例会将测试所需的时间减少一半。但症状还是一样。
我一直在对其进行分析,但没有发现任何可疑之处,除了测试需要更长的时间。

你知道这可能是什么原因吗?

编辑我正在使用com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImplcom.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl类(class)。
我猜哪些是 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 的文档,这实际上是在其中发生的)。为这些的默认实现传递系统属性接口(interface)也会解决这个问题。

总而言之,我们的性能提高了 90% 以上:-)

编辑 根据要求,我不会添加属性本身,而是添加指向 javadoc 的链接,该链接准确解释了发生的情况以及您必须执行的操作: https://docs.oracle.com/javase/7/docs/api/javax/xml/transform/TransformerFactory.html#newInstance()

这些是属性javax.xml.transform.TransformerFactoryjavax.xml.parsers.SAXParserFactory,但是,您将其设置为什么,取决于您使用的JDK和/或解析器库。

关于java - TransformerFactory.newTransformer 在测试期间变得更慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42490298/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com